您的位置:首页 > 其它

在给定字符串中找出单词并排序

2015-08-22 23:31 459 查看
2 字符串处理转换

问题描述:

在给定字符串中找出单词( “单词”由大写字母和小写字母字符构成,其他非字母字符视为单词的间隔,如空格、问号、数字等等;另外单个字母不算单词);找到单词后,按照长度进行降序排序,(排序时如果长度相同,则按出现的顺序进行排列),然后输出到一个新的字符串中;如果某个单词重复出现多次,则只输出一次;如果整个输入的字符串中没有找到单词,请输出空串。输出的单词之间使用一个“空格”隔开,最后一个单词后不加空格。

要求实现函数:

void my_word(charinput[], char output[])

【输入】 char input[], 输入的字符串

【输出】 char output[],输出的字符串

【返回】 无

示例

输入:charinput[]="some local buses, some1234123drivers" ,

输出:charoutput[]="drivers local buses some"

输入:charinput[]="%A^123 t 3453i*()" ,

输出:charoutput[]=""

我的思路:拷贝输入的字符串,然后搜索整个字符串,非字母(不满足要求的,包括单个字母)的字符变成'\0',并且记录每个单词首字母的位置和每个单词的长度

再然后,利用二重指针,把每个单词的首地址记录下来

#include<iostream>
#include<string>
using namespace std;
void choose(char *str,int len,char *outstr);
int main()
{
char str[20];
gets(str);
int len=strlen(str);
char outstr[100];
choose(str,len,outstr);
cout<<outstr<<endl;
system("pause");
return 0;
}
void choose(char *str,int len,char *outstr)
{
int count=0,r_len[100],j=0,k=0,linshi=0,word_count=0;
char temp[100],*linshi2;
strcpy(temp,str);
for(int i=0;i<=len;i++)//易犯错,注意这里需要用<=号,否则可能无法进入else导致出现问题
{
if((temp[i]>='a' && temp[i]<='z')||(temp[i]>='A' && temp[i]<='Z'))
count++;
else
{
if(count==1)
temp[i-1]='\0';
if(count>=2)
r_len[j++]=count;
count=0;
temp[i]='\0';
}
}

word_count=j;
count=0;
char **a=(char **)malloc(sizeof(char *)*len);
for(int i=0;i<len;i++)
{
if((temp[i]>='a' && temp[i]<='z')||(temp[i]>='A' && temp[i]<='Z'))
{
count++;
if(count==1)
{
a[k++]=&temp[i];
}
}
else
{
count=0;
}
}
//排序
for (int m=0;m<word_count-1;m++)
{
for(int n=word_count-1;n>m;n--)
{
if(r_len
< r_len[n-1])
{
//这里一起排序
linshi=r_len
;
r_len
=r_len[n-1];
r_len[n-1]=linshi;

linshi2=a
;
a
=a[n-1];
a[n-1]=linshi2;
}
}
}
for(int i=0;i<word_count;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
cout<<endl;
outstr[0]='\0';//注意,易错,outstr指向一块未赋值的空间,不先赋值'\0',就使用strcat会出问题,会在原有的乱码后拼接,赋值'\0'后从这里开始拼接
for(int i=0;i<word_count;i++)
{
strcat(outstr, a[i]);
int k=strlen(outstr);
outstr[k]=' ';
outstr[k+1]='\0';
}
}


参考答案:
http://blog.csdn.net/suren__123/article/details/11489899
/*
问题描述:
在给定字符串中找出单词
( “单词”由大写字母和小写字母字符构成,其他非字母字符视为单词的间隔,
如空格、问号、数字等等;另外单个字母不算单词);找到单词后,按照长度进行降序排序,
(排序时如果长度相同,则按出现的顺序进行排列),然后输出到一个新的字符串中;
如果某个单词重复出现多次,则只输出一次;如果整个输入的字符串中没有找到单词,
请输出空串。输出的单词之间使用一个“空格”隔开,最后一个单词后不加空格。
要求实现函数:
void my_word(charinput[], char output[])
【输入】  char input[], 输入的字符串
【输出】  char output[],输出的字符串
【返回】 无
示例
输入:charinput[]="some local buses, some1234123drivers" ,
输出:charoutput[]="drivers local buses some"
输入:charinput[]="%A^123 t 3453i*()" ,
输出:charoutput[]=""
*/

void my_word(char input[], char output[])
{

//给字符串后面加空格方便后面对字符串进行分割
//注意,在使用这个函数的时候需要给input预留足够的长度,传递的必须是数组变量
//不能是字符串常量字符串常量无法修改,第二个参数可以是常量
//感觉这里最好使用strcpy复制一下可能更好,因为input可能是常量,无法修改
strcat(input," ");

//字符串的分割结果
char p[100][100];
//每个字符串的长度
int lenth[100];
//字符串个数
int word = 0;

int start = 0;
int end = 0;
int flag = 0;

int pi = 0;
int pj = 0;
int pl = 0;
int flag2 = 0;

for(int i = 0;input[i]!='\0';i++)
{

//判断是否是字符
if((input[i]>='a'&&input[i]<='z')||(input[i]>='A'&&input[i]<='Z'))
{
//判断是否为首次出现,若是则记录首次出现位置
if(flag==0)
{
start = i;
}
//计算连续出现次数
flag++;

}else//不是字符
{
//若连续出现次数大于1,若是则记录最后出现位置
if(flag>1)
{
end = i;
//cout<<start<<end<<endl;

//此时能够得出每个单词的起始位置还有每个单词的长度
//分割字符串,并复制到中间变量中
//使用字符串截取函数需注意在后面添加结束标志
char temp[100];

strncpy(temp,&input[start],end-start);
temp[end-start]= '\0';

//这里要判断是否重复
for(int j = 0;j< pi ; j++)
{
if(strcmp(p[j],temp)==0)
{
flag2 = 1;
break;

}else
{
flag2 = 0;
}

}

//若不重复则保存
if(flag2==0)
{
strcpy(p[pi],temp);
//保存单词长度数组
lenth[pi] = flag;
printf("%s\n",p[pi]);
printf("%d\n",lenth[pi]);
pi++;
}

}
//连续出现次数清零
flag = 0;
}

}

char temp[100] ;
int temp2 = 0;

//根据单词长度数组对单词数组进行排序
for(int i = 0 ;i <= pi; i++)
{
for(int j = i ;j <= pi; j++)
{
if(lenth[i]<lenth[j])
{
lenth[i] = temp2;
lenth[i] =  lenth[j];
lenth[j] = temp2;

strcpy(temp,p[i]);
strcpy(p[i],p[j]);
strcpy(p[j],temp);

}
}
}

//对排好序的单词数组进行重新连接
for(int i = 0 ;i <= pi; i++)
{

//字符串连接函数
strcat(output,p[i]);

//这里需注意最后一个单词无需加空格
if(i < pi-1)
{
strcat(output," ");

}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: