题目描述
对给定的一个字符串,找出有重复的字符,并给出其位置,如:abcaaAB12ab12 输出:a,1;a,4;a,5;a,10,b,2;b,11,1,8;1,12, 2,9;2,13。
输入描述:
输入包括一个由字母和数字组成的字符串,其长度不超过100。
输出描述:
可能有多组测试数据,对于每组数据,
按照样例输出的格式将字符出现的位置标出。
1、下标从0开始。
2、相同的字母在一行表示出其出现过的位置。
示例1
输入
abcaaAB12ab12
输出
a:0,a:3,a:4,a:9
b:1,b:10
1:7,1:11
2:8,2:12
abcaaAB12ab12
a:0,a:3,a:4,a:9
b:1,b:10
1:7,1:11
2:8,2:12
答案
/*********************************
* 日期:2013-2-19
* 作者:SJF0115
* 题号: 九度OJ 题目1199:找位置
* 来源:http://ac.jobdu.com/problem.php?pid=1199
* 结果:AC
* 来源:2005年华中科技大学计算机保研机试真题
* 总结:
**********************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct Character{
char c;//字符
int count;//统计这种字符的个数;统计时,可以用来表达字符串中这种字符第count次出现
int location[101];//记录一个字符串中同一个字符的不同位置。
int flag;//标记已输出
} Character;
int main()
{
int i,index,j;
char str[101];
Character c[150];
while(gets(str)){
//初始化
for(i = 0;i < 150;i++){
c[i].count = 0;
c[i].flag = 0;
}
//统计字符个数,字符位置
for(i = 0;i < strlen(str);i++){
//利用单个字符的十进制数来作为索引,将str[i]放入当前结构体变量的成员c中
c[str[i]].c = str[i];
//利用count作为成员location数组的索引,放入位置i后,count++。记录位置后再记录第几次出现。出现的次数有和位置的索引有关
//语义:这个字符串中这个字符第count次出现,出现的位置为i ,这个信息放在location[count - 1]中。
//这些位置信息都是从location[0]中开始存放的。第一次出现的位置放在location[0]中。
index = c[str[i]].count;
c[str[i]].location[index] = i;
//成员count++,完善这种字符的这次出现的记录信息。
c[str[i]].count++;
}
//因为str有这么长,所以要for这么多次。
for(i = 0;i < strlen(str);i++){
//有重复的字符且没有输出过
//将字符转为了int,之前赋值给结构体数组时,不同的字符所在位置的索引为该字符的十进制。
//得到当前字符的索引,这就决定了先输出哪种字符。但当前字符可能已经输出过了。所以有if判断。
index = str[i];
//这种字符有一个还是多个
//c[index].count > 1 说明这种字符不止一个,要继续输出;
//c[index].flag == 1 说明这种字符,已经打印完了。
//c[index].flag == 0这个条件是为了防止遍历到后面,继续输出之前输出的不止一个的字符。
//实现每一种字符的位置信息只输出一次
if(c[index].count > 1 && c[index].flag == 0){
//输出重复字符
//这种字符只出现过一次的话,就不会执行for,c[index].count==1 。
for(j = 0;j < c[index].count-1;j++){
printf("%c:%d,",str[i],c[index].location[j]);
}
//以\n来收尾,无论一次还是多次出现,都没有, 结尾。去,结尾,改变结尾的形式
printf("%c:%d\n",str[i],c[index].location[j]);
//标记已读;已输出
c[index].flag = 1;
}
}
}
return 0;
}