电话号码整理问题
Description
商业单位需要容易记忆的电话号码,有一些方法可以让电话号码变得更容易记忆。譬如,可以把电话号码写成单词或短语,如 MON-GLOP 可以代表滑铁卢大学的电话。有时仅仅是把号码的一部分写成单词,如打 310-GINO 便可向 GINO 比萨饼店定购比萨。另一种让电话号码容易记忆的方法是将数字用一种容易记的方式组合起来,譬如 3-10-10-10 也可以代表 GINO 比萨饼店。
电话号码的标准形式是七位十进制数字,在它的第三位和第四位之间用连字符连接(例如:666-1200)。电话的键盘提供了字符与数字之间的映射关系,如下所示:
Q 和 Z 没有映射到键盘,而连字符不需要被拨打并且可以根据需要任意添加和删除。MON-GLOP 的标准形式是 666-4567,310-GINO 的标准形式是310-4466,3-10-10-10的标准形式也是 310-1010。
如果两个电话号码有相同的标准形式,那么这两个电话号码是相同的。
你所在的公司正在编辑一本当地商业单位的电话簿,作为质量控制流程的一部分,你需要确认在该电话簿中有没有错误的电话号码,以及有没有两个(或两个以上的)商业单位使用相同的电话号码。由于当地只使用了 3 和 6 两个区段,因此电话号码的第一个数字应当永远是 3 或者 6,如果出现了其它数字,就表示这个电话号码错了。此外,如果电话号码中出现了 Q 和 Z,也说明这个电话错了。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<locale.h>
static unsigned char hash_str[250010];
static struct table
{
long long int tele_numb;
int dupli_time;
};
static struct table result[1510];
long long int str_trans(char*);
int check_dupli(long long int, int);
int cmp(const void*, const void*);
int main()
{
int t;
long long int i, sta;
char str[21];
int count_error = 0, count_dupli = 0;
printf("Error:\n");
while(scanf("%s", str)!=EOF)
{
t = getchar();
sta = str_trans(str);
if (sta == 0)
{
printf("%s\n", str);
count_error++;
}
else
{
count_dupli = count_dupli + check_dupli(sta, count_dupli);
}
}
if (count_error == 0)
{
printf("Not found.\n");
}
printf("\nDuplication:\n");
if (count_dupli == 0)
{
printf("Not found.\n");
}
else
{
qsort(result, count_dupli , sizeof(struct table), cmp);
for (i = 0; i < count_dupli; i++)
{
printf("%lld-", ((result[i]).tele_numb / 10000));
printf("%04lld ",((result[i]).tele_numb % 10000));
printf("%d\n", (result[i]).dupli_time + 1);
}
}
}
long long int str_trans(char* str0)
{
char* p;
long long int number = 0;
int flag = 1, count = 0;
p = str0;
while (1)
{
if (*p == '\0')
{
break;
}
if (*p == 'Q' || *p == 'Z')
{
flag = 0;
break;
}
if (*p == '-')
{
p++;
}
else if (count == 0 && *p != '3' && *p != '6'&& *p != 'D' && *p != 'E' && *p != 'F'&& *p != 'M' && *p != 'N' && *p != 'O')
{
flag = 0;
break;
}
else
{
if (*p == 'A' || *p == 'B' || *p == 'C' || *p == '2')
{
number = number * 10 + 2;
count++;
}
else if (*p == 'D' || *p == 'E' || *p == 'F' || *p == '3')
{
number = number * 10 + 3;
count++;
}
else if (*p == 'G' || *p == 'H' || *p == 'I' || *p == '4')
{
number = number * 10 + 4;
count++;
}
else if (*p == 'J' || *p == 'K' || *p == 'L' || *p == '5')
{
number = number * 10 + 5;
count++;
}
else if (*p == 'M' || *p == 'N' || *p == 'O' || *p == '6')
{
number = number * 10 + 6;
count++;
}
else if (*p == 'P' || *p == 'R' || *p == 'S' || *p == '7')
{
number = number * 10 + 7;
count++;
}
else if (*p == 'T' || *p == 'U' || *p == 'V' || *p == '8')
{
number = number * 10 + 8;
count++;
}
else if (*p == 'W' || *p == 'X' || *p == 'Y' || *p == '9')
{
number = number * 10 + 9;
count++;
}
else if (*p == '1' || *p == '0')
{
number = number * 10 + *p - '0';
count++;
}
p++;
}
}
if (count != 7)
{
flag = 0;
}
if (flag == 0)
{
return 0;
}
else if (flag == 1)
{
return number;
}
else return -1;
}
int check_dupli(long long int stat, int j)
{
long long int x, y, f;
int k, flag = 1;
f = stat / (long long int)1000000;
if (f == 3)
{
x = (stat % (long long int)1000000) / 8;
}
else if (f == 6)
{
x = (long long int)125000 + (stat % (long long int)1000000) / 8;
}
y = stat % 8;
if (((hash_str[x] >> y) & 1) == 0)
{
hash_str[x] = hash_str[x] | (1 << y);
return 0;
}
else if (((hash_str[x] >> y) & 1) == 1)
{
for (k = 0; k < j; k++)
{
if (stat == result[k].tele_numb)
{
result[k].dupli_time++;
flag = 0;
}
}
if (flag == 1)
{
result[j].tele_numb = stat;
result[j].dupli_time++;
return 1;
}
else if (flag == 0)
{
return 0;
}
}
else return -1;
}
int cmp(const void* a, const void* b)
{
return ((*(struct table*)a).tele_numb > (*(struct table*)b).tele_numb) ? 1 : -1;
}