有两题,想了很久都想不到应该怎么写,哪位大侠帮帮忙啊?

2024-11-14 14:34:12
推荐回答(5个)
回答(1):

第二题你可以设计一个块链结构放短文中的单词,再将这些块链连接起来,就是整个短文了;然后在设计一个search算法进行统计;整个算法约三、四百行代码;这是那个严蔚敏版本地数据结构字符串那章的课程设计,我做过,所以n年后还有些印象,你是不是偷懒不想做,不过给的分挺诱人,我找找以前的笔记,若还存在就给你一个copy,

我找到了以前的算法,我做的那个课程设计比你这个要复杂些,题为,从键盘输入任意个单词,然后在所给的一篇文章中搜索并进行统计输入的单词在文章中出现的次数;你把我这个数据结构删除在精简在做几处改动就行了,至于具体这几处的修改你应该自己动手了,不然这算法你是啥也学不到;这边贴上代码,

// 几个简单的字符操作函数.cpp : Defines the entry point for the console application.
/*
算法的基本思想是:
利用两个块链,一个放输入的单词,另外一个放从文件中读入的一行的单词,
然后从第一个块链单词中取出一个单词开始与另一块链中的单词比较,比较
结束再把从文件中读入块链删除,开始从文件中读入下一行,直到将文件遍
历一遍将找到的相同的结果保存。然后将指针移向存放输入单词块链的下一
个单词继续开始文件的第二次遍历。直至将输入块链中的单词全部比较结束
为止。遍历的次数即为输入单词的个数。

伪码算法如下所示:
STATUS COMPARE( )
{
while(输入块链不为空)
{
while(文件被访问结束标志变量)
{
while(从文件中读入的一行不为空)//此循环执行一行的比较
{
输入块链中的一个单词与读入的一行进行逐个比较若相等则
调用record()函数保存结果

}
删除从文件中读入的块链,重新读入文件中的下一行,
并判断文件是否已经读到最后,若是则置标志变量值
用于判断是否结束循环。
}
文件已被访问到最后,即已经遍历一次。
将输入块链中的指针指向下一个单词,再次开始从文件中读入
一行开始下一次遍历,进行下一轮的比较

}

关于存储结构的说明:
结构体数组word存放每个输入单词在文件中出现的次数以及指向存放单词
出现的行数的结构体首指针
结构体result存放单词出现的行数信息。
chunk为存放输入块链的结构体,word1为存放从文件中读入的块链结构体。

运行方式:
运行是先输入要统计的单词,单词之间用空格分开,结束输入则在单词
末尾加上一个@ ,如: abc bb dlkf@
然后输入完整的路径及文件名称和文件的后缀名,如 e:\asd.txt

备注:此代码已调试通过。可以运行

}

*/

#include
#include
#include
#include
//从文件中读入的单词的块链存储
struct chunk//一个块链里面放一个单词
{
char ch[20];//单词的最大长度为二十个字符
struct chunk * next;//每一个块链指向下一个的连接指针
};

//从键盘上输入的单词的块链存储
struct word1
{
char chw[20];
struct word1 *link;
};

struct result // 已经查找到的字符的存储结构
{
int line; //出现在第几行
struct result *next ; //下一个相同的字符的位置

};
struct word
{
int n; //待查询的每个单词总共出现的次数
struct result * head; //指向每个待查询单词的首个存储记录
};

struct word wrd[10]={{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}};
FILE * fpmid=0;//用于传递文件指针的中间变量
int sign=0;//标志变量用于判断文件是否被访问到结束处
int bltimes=0;//标志文件被遍历的次数

struct chunk * read(FILE * fp)
{
struct chunk *p ,*q,*head;
char a; int i=0,end=0;
char filename[10];static one=1;

if (one==1)
{
printf("please input the name of file :\n");
scanf("%s", filename);
if((fp=fopen(filename,"r"))==NULL)
{
cout<<"cannot open file"<}

} p=new struct chunk ;
head=p; q=p;

while(!feof(fp))
{
a=fgetc(fp);
//以下的算法将从文件中读入的单词放到一个创建的链里面

if(a!=' ')
{
if(a=='\n')
{
break;

}
p->ch[i++]=a ;

}
else
{
while(i<20)//此循环将字符后面的空间都赋于空值
{
p->ch[i++]='#';
}
q=new struct chunk;
p->next=q;
p=q;
i=0;
}

}
while(i<20)//此循环将字符后面的空间都赋于空值
{
p->ch[i++]='#';
}
p->next=0;//一行的结点末尾指针为空
printf("\n");
//将读入的一行字符显示出来
cout<<"文件中的一行的字符显示如下:"<i=0; p=head;
while (p!=0 )
if(p->ch[i]!='#')
putchar(p->ch[i++]);
else
{
printf(" ");//输出一个空格将单词隔开
p=p->next ;
i=0;
}
cout<<"\n\n";
one++;

if(feof(fp)) //判断文件是否结束如果结束则重置文件指针到开头
{
rewind(fp);
sign=1;//标志文件是否被访问到底的变量
}

fpmid=fp;//赋值
return(head); //将文件中的一行首指针返回用于比较

}

struct word1 * input()
{ char a; int i=0,end=0;
struct word1 *wp,*wq,*whead;
cout<<"请输入待统计的单词"<
wp=new struct word1;
i=0;
whead=wp;
wq=wp;
a=getchar();//
while(a!='@') //如果输入的字符为@则结束输入
{
if(a!=' ')
{
wp->chw[i]=a;
// putchar(wp->chw[i]);
i++;

}
else
{
while(i<20) //此循环将字符后面的空间都赋于#
{
wp->chw[i]='#';
i++;
}
wq=new struct word1;
wp->link=wq;
wp=wq;
i=0;
}
a=getchar();

}
while(i<20) //此循环将字符后面的空间都赋于#
{
wp->chw[i]='#';
i++;
}

wp->link=0;

cout<<"将输入的块链显示出来"<
//将输入的块链显示出来

i=0;wp=whead;
while(wp!=0)
{
if(wp->chw[i]!='#')
putchar(wp->chw[i++]) ;
else
{
printf(" ");
wp=wp->link ;
i=0;
}

}

printf("\n\n");
return(whead);

}
void destory( struct chunk *q)
{
struct chunk *p;
while(q)
{
p=q->next ;
delete(q);
q=p;
}

}

struct result * record (int filelines,struct result * mid,struct word *shuzu)
{ //此函数是将经过比较相等的字符所在的行存储起来,
struct result *p;
if(shuzu->n==0 )
{
p=new struct result;
shuzu->head=p;
p->line=filelines;
mid=p;
p->next=0;

}
else
{
p=new struct result;
p->line=filelines;
mid->next=p;//前面的指向后面的从而将已创建的链表连接起来
mid=p;
p->next=0;
}
shuzu->n++ ;
cout<<"指针已经加一了噢!"<n<return(mid);
}

void compare(struct word1 *p, struct chunk *q)
{
int i=0;
int filelines=0;//文件的行数
struct result *mid=0;
struct word *shuzu=0;//指向结构体数组的指针
struct chunk *qhead;
qhead=q;
shuzu=wrd;//赋于结构体数组首地址

while(p)//若输入块链比较结束,则整个比较过程结束
{
filelines=0; mid=0;
while(1)//此循环结束即为遍历所访问的文件一遍
{
if(sign==1)//sign是文件是否被访问到最后的标志变量
sign++; //如果条件符合则下面比较的是文件的最后一行
while(q) //此循环比较一行
{ //就是输入的一行单词的一个与文件中的一行的比较

for(i=0;i<20;i++)//比较字符是否相等,抱歉这里不能用字符比较函数strcmp
{
if(p->chw[i]!=q->ch[i])
break;
}

if(i==20)//满足此条件即经比较有相等的字符出现
{
cout<<"有相同的单词:"<shuzu=wrd;
mid=record(filelines,mid,shuzu+bltimes);//记录经比较相等的结果
}
q=q->next ; //指向文件中这一行的下一个单词
i=0;
}//while(q)

destory(qhead);//第一行已经检查完毕,将其空间删除再读入文件的
//下一行继续与输入行中的一个单词比较直至到文件末尾
q=read(fpmid) ; //返回的是文件中的一行首指针以用于上面的比较
filelines++ ;
if(sign==2) //若此条件满足则上一行的q是指向文件的首行再次
{ //开始比较了,即此条件执行则文件已经遍历一遍
sign=0;
break;
}
}//while(1)
p=p->link ;//输入的待比较的块链中的下一个单词
bltimes++;//标志文件被遍历的次数
cout<<"遍历的次数为:"<cout<<"\n\n";
}//while
fclose(fpmid);//关闭文件
}

void output( struct word1 *whead)
{
struct word *p,*hword;
struct result *q;
int i=0;

p=wrd;
hword=wrd;
while(whead)
{
if(p->n!=0)

while(whead->chw[i]!='#')
{ putchar(whead->chw[i]) ;
i++;
}
printf(" ");
i=0;
cout<<"单词在文件中出现"<n<<"次 ";
q=p->head ;
cout<chw<<"单词在文件中出现"<n<<"次 "<q=p->head ;
while(q)
{
cout<<"出现在第"<<++q->line<<"行 ";
q=q->next ;

}
cout<<"\n";
}
else
{

/*while(whead->chw[i]!='#')//输出单词
putchar(whead->chw[i++]) ;
printf(" ");
*/ i=0;

cout<chw<<"单词没有在文件中出现!"<
}

whead=whead->link ;
hword++;
p=hword;

}//while(whead)

}

void main()
{
struct word1 *p,*whead;
struct chunk *q;

p=input();//从键盘输入的待比较的字符放入一块链中

whead=p;

q=read(fpmid);//从文件中读入一行字符放入块链中

compare(p,q);//比较函数

output(whead);//输出比较结果

}

问题补充:侠胆熊虎兄,非常感谢你那么的热心,可是我也说了,我是初学者,你写的那些太深了,我指针都还没学呢。

晕了,那就用数组做了(虽然数组计算也是用指针实现的),
算法思想,
把你那个不超500字符短文全放到一个字符数组中,,单词这间用空格分开,如 char str[]="asd dff ...";
然后搜索并比较,过程这般,用一个循环,在这之中遇到空格,则读入一个单词,进行比较,记录结果,然后在读入下一个单词进行比较,直至结束。

算法如此这般,
#include
void main()
{

char str[]="......."; ///放短文单词集合
int i=0;
int flag=0; ////为a个数

if('a'==str[i]) ///比较第一个单词
flag=flag+1;

///比较其他
while(str[i]!='\0')////字符结束标志
{

while(str[i]!=' ')
{
i=i+1;

}
i=i+1;
if('a'==str[i])
flag=flag+1;

}

}

回答(2):

写程序时没有时间了,
说一下思路吧,
这两题其实不需要太复杂的知识,说一下方法,应该自己完全能想明白,
初学者自己一定能够要多动手,多思考,
特别忌讳直接拿别人代码,知其然不知其所以然。

第一题:
其实这个题目是考察对于二维/多维的实际存储方法是否了解。
不论是几维数组,在计算机中,一定是线性连续存储的,
所谓n维只是它的空间建模。
所以4*4的二维数组,在计算机中是一个16个数组成员线性连续存储的数组。
完全可以通过一维下标来定位和遍历。
例如:就存储位置来说,a[0][0]就是a[0],a[1][2]就是a[5],a[4][4]就是a[15]

所以这一题就可以将二维数组录入后(例如定义为a[4][4]),对于a[16]的数组进行排序。
这个应该没问题吧,至少冒泡肯定会吧:)

第二题:
你说还没学过指针,这个就比较麻烦了,
至少可以这么做。
将整个短文考到一个字符数组(也就是字符串了)中。
然后从头开始遍历。
定义一个标志位(初始化为FALSE),凡是遇到'a'或者‘A’,将标志位置为TRUE,
再向后遍历,每次遇到空格都判断标志位是否为TRUE,如果是,则将计数加1,然后将标志位再置为FALSE,继续遍历,直到串尾。

回答(3):

1、
#include
int main()
{
int a[4][4]={0};
int i,j,temp,*p;

//输入
printf("请输入一个4行4列的矩阵:\n");
for(i=0;i<4;i++)
for(j=0;j<4;j++)
scanf("%d",&a[i][j]);

//冒泡排序
p=&a[0][0];
for(i=0;i<4*4;i++)
for(j=4*4-1;j>i;j--)
if(p[j]>p[j-1])
{//交换
temp=p[j];
p[j]=p[j-1];
p[j-1]=temp;
}

//输出
printf("排序后的矩阵是:\n");
for(i=0;i<4;i++)
{
for(j=0;j<5;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
return 0;
}

2、
#include
int main()
{
int c,b=1,f=0,s=0; //b表示单词开头,f表示以a开头,s计数

while((c=getchar())!='\n')
{
if(c=='a'&&b)
{
f=1;
b=0;
}
else if(c==' ')
{
if(f) s++;
b=1;
f=0;
}
else
{
b=0;
}
}
if(f) s++;
printf("%d\n",s);
return 0;
}

回答(4):

第一题我就不做了,你也会了,不知只做第二题你是否会给分啊。
定一个适合初学者的,不用指针,只用下标法。
英文单词是以空格或换行符等不可打印的字符分隔。用这库函数检测。
int isspace(int ch) 若ch是空格(' '),水平制表符('\t'),回车符('\r'),走纸换行('\f'),垂直制表符('\v'),换行符('\n')返回非0值,否则返回0
int tolower(int ch) 若ch是大写字母('A'-'Z')返回相应的小写字母('a'-'z')

主要用这两库函数,在ctype.h头文件中
下面给出程序。
#include
#include
main(){
char str[501];
int i,j,num;
printf("\nEnter text,lose than 500 char: ");
gets(str);
i=0;
num=0;
while(1){
if(str[i]=='\n')
break;
if(i==0){
if(tolower(str[i])=='a')
num++;
}
else{
if( (tolower(str[i])=='a')&& isspace(str[i-1]))
num++;
}

i++;
if(i>500)
break;
}

printf("\nIn text have %d a..word.",num);

getchar();
}

回答(5):

我也是初学者,所以..收藏了...
第一个也许能行,第二个不会。
第二题
请问如何判断是一个单词?是否a[i]不是字母不是数字,a[i+1]就是单词的第一个字母? 或者这样的判断是否可行?
初步的想法是
char a[50];
int i,n=0;
gets(a);
for(i=0;i<50;i++)
{
if(a[i]不是数字不是字母&&(a[i+1]=='a'||a[i+1]=='A')
n++;
}

//再判断a[0]='A',不然一上来不空格就开始打个A开头的,容易漏掉吧
if(a[0]=='a'||a[0]=='A')
n++;

不知道这个想法对不对,请指教