用C语言编写一个判断关系矩阵的程序。(离散数学额问题)
我遇到了一个小问题,希望有人可以帮帮我。
这个程序是很简单的,可是,我们老师要求我们用int main(int argc, char *argv[])
我不懂,希望大家帮我下。
下面是我的程序。
int main(int argc, char *argv[])
{
FILE *fp;
fp = ("argv[1]", "r");
}
是这样写的吗??
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void Reflexive(int a[100][100], int n)
{
int i;
for(i = 0; i < n; i++)
if(a[i][i] == 0)
{
printf("not reflexive, ");/*主对角线有一个为0即输出不是自反,跳出循环*/
break;
}
if(i == n)
printf("reflexive, ");/*如果循环全作一遍,则为自反*/
}
/*判断自反*/
void Reflexiveness(int a[100][100], int n)
{
int i;
for(i = 0; i < n; i++)
if(a[i][i] == 1)
{
printf("not reflexiveness, ");/*主对角线有一个为q即输出不是反自反,跳出循环*/
break;
}
if(i == n)
printf("reflexiveness, ");/*如果循环全作一遍,则为反自反*/
}
/*判断反自反*/
void Symmetry(int a[100][100], int n)
{
int i, j;
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
if(a[i][j] == a[j][i])/*如果关于主对角线对称的元素相等,则跳过下面的语句,继续循环*/
continue;
printf("not symmetry, ");/*上面的条件不符,即关于主对角线对称的元素不等,则输出不是对称,跳出循环*/
break;
}
if(j != n)
break;/*不是对称,跳出循环*/
else if(i == n-1 && j == n)
printf("symmetry, ");/*所有的元素都遍历了,没有不合对称条件的,输出对称*/
}
}
/*判断是否对称*/
void Antisymmetry(int a[100][100], int n)
{
int i, j, s = 1;/*用s作为不合条件时的标记*/
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
if((a[i][j] == 1 && a[j][i] == 1) && (i != j))
{
s = 0;/*s = 0 时,不是反对称,跳出循环*/
break;
}
}
if(s == 0)
{
printf("not antisymmetry, ");/*判断s的值,为0,则输出不是反对称*/
break;
}
}
if(s == 1)/*s = 1时,输出反对称*/
printf("antisymmetry, ");
}
/*判断是否反对称*/
void Transitive(int a[100][100], int n)
{
int i, j, k;
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
if(a[i][j] == 0)/*对所有元素一一遍历,等于0时作下面的工作*/
{
for(k = 1; k < n; k++)
if(a[i][k] == 1 && a[k][j] == 1)/*不是传递的判断,输出不是传递,推出整个程序*/
{
printf("not transitive.\n");
exit(0);
}
}
}
printf("transitive.\n");/*否则,输出传递*/
}
/*判断是否传递*/
void main()
{
FILE *fp;
int i = 0, j, n, k, s = 0;
int b[10000], a[100][100];
fp = fopen("a.txt", "r");
if(!fp)
{
printf("Can not open !");
exit(0);
}
while(!feof(fp))
{
b[i] = fscanf(fp, "%d", &k);
i = i + 1;
}
n = (int)sqrt(i);
fclose(fp);
fp = fopen("a.txt", "r");
while(!feof(fp))
{
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
fscanf(fp, "%d", &a[i][j]);
}
printf("The relation is:\n");
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
printf("%-3d", a[i][j]);
printf("\n");
}
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
if(a[i][j] == 1)
{
s = 1;
break;
}
if(j != n)
break;
}
if(!s)
printf("reflexive, ");
else
Reflexive(a, n);
Reflexiveness(a, n);
Symmetry(a, n);
Antisymmetry(a, n);
Transitive(a, n);
}
其中a.txt为一个矩阵
例如:
1 0 1
0 1 0
0 0 0
输出:
not reflexive, not reflexiveness, not symmentry, antisymmetry, transitive.
[解决办法]
int main(int argc, char *argv[])
{
FILE *fp;
fp = fopen("argv[1]", "r"); //最好判断一下是否打开(fopen()是否为NULL)
}
[解决办法]
argv[0]:第一个参数(当前程序可执行文件)
argv[1]:第二个参数(要打开的文件名称)
[解决办法]
程序看了一下,逻辑上应该没有大问题。
就是几个判断函数的处理方式感觉有点怪异。
有时间帮你重写一下。
- C/C++ code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void Reflexive(int a[100][100], int n)
{
int i;
for(i = 0; i < n; i++)
if(a[i][i] == 0)
{
printf("not reflexive, ");/*主对角线有一个为0即输出不是自反,跳出循环*/
break;
}
if(i == n)
printf("reflexive, ");/*如果循环全作一遍,则为自反*/
}
/*判断自反*/
void Reflexiveness(int a[100][100], int n)
{
int i;
for(i = 0; i < n; i++)
if(a[i][i] == 1)
{
printf("not reflexiveness, ");/*主对角线有一个为q即输出不是反自反,跳出循环*/
break;
}
if(i == n)
printf("reflexiveness, ");/*如果循环全作一遍,则为反自反*/
}
/*判断反自反*/
void Symmetry(int a[100][100], int n)
{
int i, j;
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
if(a[i][j] == a[j][i])/*如果关于主对角线对称的元素相等,则跳过下面的语句,继续循环*/
continue;
printf("not symmetry, ");/*上面的条件不符,即关于主对角线对称的元素不等,则输出不是对称,跳出循环*/
break;
}
if(j != n)
break;/*不是对称,跳出循环*/
else if(i == n-1 && j == n)
printf("symmetry, ");/*所有的元素都遍历了,没有不合对称条件的,输出对称*/
}
}
/*判断是否对称*/
void Antisymmetry(int a[100][100], int n)
{
int i, j, s = 1;/*用s作为不合条件时的标记*/
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
if((a[i][j] == 1 && a[j][i] == 1) && (i != j))
{
s = 0;/*s = 0 时,不是反对称,跳出循环*/
break;
}
}
if(s == 0)
{
printf("not antisymmetry, ");/*判断s的值,为0,则输出不是反对称*/
break;
}
}
if(s == 1)/*s = 1时,输出反对称*/
printf("antisymmetry, ");
}
/*判断是否反对称*/
void Transitive(int a[100][100], int n)
{
int i, j, k;
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
if(a[i][j] == 0)/*对所有元素一一遍历,等于0时作下面的工作*/
{
for(k = 1; k < n; k++)
if(a[i][k] == 1 && a[k][j] == 1)/*不是传递的判断,输出不是传递,推出整个程序*/
{
printf("not transitive.\n");
exit(0);
}
}
}
printf("transitive.\n");/*否则,输出传递*/
}
/*判断是否传递*/
/*
* 带命令行参数的 main: argc 参数个数, argv 各个参数的值(字符串)
void main()
*/
int main(int argc,char *argv[])
{
FILE *fp;
int i = 0, j, n, k, s = 0;
int b[10000], a[100][100];
/*
* 添加命令行参数处理
*/
if(argc < 2){
printf("Usage :\n <程序名> <input-file-name>\n\n");
exit(1);
}
fp = fopen(argv[1], "r");
if(!fp)
{
printf("Can not open !");
exit(0);
}
while(!feof(fp))
{
b[i] = fscanf(fp, "%d", &k);
i = i + 1;
}
n = (int)sqrt(i);
/*
* 如果要从头再次读取,不必这样关闭再打开
fclose(fp);
fp = fopen("a.txt", "r");
*/
fseek(fp,0,SEEK_SET); /* 这样就可以从头再读 */
while(!feof(fp))
{
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
fscanf(fp, "%d", &a[i][j]);
}
printf("The relation is:\n");
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
printf("%-3d", a[i][j]);
printf("\n");
}
/*
* 这里的循环是做什么的?
* 判断关系集合是否为空?
*/
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
if(a[i][j] == 1)
{
s = 1;
break;
}
if(j != n)
break;
}
/*
* 如果前面是判断关系集是否为空
* 那么这里要改一下
*/
if(s)//if(!s)
printf(" <Empty Set>\n");
else{ // 这里需要放在一对“{}”中
Reflexive(a, n);
Reflexiveness(a, n);
Symmetry(a, n);
Antisymmetry(a, n);
Transitive(a, n);
}
}
[解决办法]
改写了一下,判断逻辑基本没变。
其中判断是否传递的貌似有些问题,改了一下。
- C/C++ code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*
* 判断自反
*/
bool Reflexive(int a[100][100], int n)
{
int i;
for(i = 0; i < n; i++)
if(a[i][i] == 0)
return false;
return true;
}
/*
* 判断反自反
*/
bool Reflexiveness(int a[100][100], int n)
{
int i;
for(i = 0; i < n; i++)
if(a[i][i] == 1)
return false;
return true;
}
/*
* 判断是否对称
*/
bool Symmetry(int a[100][100], int n)
{
int i, j;
for(i = 0; i < n - 1; i++){
for(j = i + 1; j < n; j++){
if(a[i][j] != a[j][i])
return false;
}
}
return true;
}
/*
* 判断是否反对称
*/
bool Antisymmetry(int a[100][100], int n)
{
int i, j;
for(i = 0; i < n - 1; i++){
for(j = i + 1; j < n; j++){
if((a[i][j] == 1 && a[j][i] == 1) && (i != j))
return false;
}
}
return true;
}
/*
* 判断是否传递
*/
bool Transitive(int a[100][100], int n)
{
int i, j, k;
for(i = 0; i < n; i++){
for(j = 0; j < n; j++){
if(a[i][j] == 1){ /* 若ij存在关系,则对所有与 j 存在关系的必与 i 存在关系,是为传递 */
for(k = 0; k < n;k++){
if(a[j][k] == 1 && a[i][k] != 1)
return false;
}
}
}
}
return true;
}
/*
* 判断是否为空
*/
bool isEmptySet(int a[100][100], int n){
int i,j;
for(i = 0;i < n;i++){
for(j = 0;j < n;j++)
if(a[i][j])
return false;
}
return true;
}
int main(int argc,char *argv[])
{
FILE *fp;
int i = 0, j, n;
int b[10000], a[100][100];
if(argc < 2){
printf("Usage :\n <程序名> <input-file-name>\n\n");
exit(0);
}
fp = fopen(argv[1], "r");
if(!fp){
printf("Can not open !");
exit(0);
}
while(!feof(fp)){
fscanf(fp, "%d", b + i++);
}
fclose(fp);
n = (int)sqrt(i);
/* 直接用坐标映射,不需要再次读取文件 */
for(j = 0;j < i;j++){
a[j/n][j % n] = b[j];
}
printf("The relation is:\n");
for(i = 0; i < n; i++){
for(j = 0; j < n; j++)
printf("%-3d", a[i][j]);
printf("\n");
}
if(isEmptySet(a,n))
printf(" <Empty Set>\n");
else{
if(!Reflexive(a, n)) printf("not "); printf("reflexive, ");
if(!Reflexiveness(a, n))printf("not "); printf("reflexiveneww, ");
if(!Symmetry(a, n)) printf("not "); printf("symmetry, ");
if(!Antisymmetry(a, n)) printf("not "); printf("antisymmetry, ");
if(!Transitive(a, n)) printf("not "); printf("transitive.\n");
}
return 1;
}
测试例 1:
1 0 1 1
0 1 0 1
0 0 0 0
0 0 0 1
输出:
not reflexive, not reflexiveneww, not symmetry, antisymmetry, transitive.
测试例 2:
1 0 1 0
0 1 0 1
1 0 1 0
0 0 0 1
输出:
reflexive, not reflexiveneww, not symmetry, not antisymmetry, transitive.
测试例 3:
0 0 1 0
0 0 0 1
1 0 0 0
0 1 0 0
输出:
not reflexive, reflexiveneww, symmetry, not antisymmetry, not transitive.