求电话本的算法,谢谢啦!

紫色动力 2011-03-23 01:14:33
想做个电话本的程序,把公司同事的电话号码都放上。类似手机上的号码查询,用名字拼音的第一个字母进行查询。比如输入"M",把姓氏拼音第一个字母是"M"名字全找出来。输入“MX”,把名字前两个字第一个拼音是“MX”的名字找出来,比如把“马小军”,“马小丽”等名字找出来。请问这个算法怎么写,万分感谢!!!!
...全文
262 12 打赏 收藏 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
紫色动力 2011-04-21
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 tangsun1227 的回复:]
算法珠玑里第一个例子
[/Quote]
请问和《编程珠玑》是一本书吗?
紫色动力 2011-03-24
  • 打赏
  • 举报
回复
谢谢!!
紫色动力 2011-03-24
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 tangsun1227 的回复:]
算法珠玑里第一个例子
[/Quote]
谢谢,我去找找这本书。
qq120848369 2011-03-23
  • 打赏
  • 举报
回复
#include<iostream>
#include <set>
#include <string>
#include <queue>
using namespace std;

typedef struct node
{
public:
node()
{
memset(table,0,sizeof(table));
}

public:
set<string> name;
node* table[26];
}Node;

typedef struct trie
{
public:
trie():count(0)
{
}

public:
Node root;
int count;
}Trie;

Trie* createTrie()
{
return new Trie();
}

Node* createNode()
{
return new Node();
}

bool insert(const char *code,const char *name,Trie *tree)
{
Node *cur=&tree->root;

while(*code!=0)
{
if(cur->table[*code-'a']!=NULL)
{
cur=cur->table[*code-'a'];
}
else
{
Node *next=new Node();
cur->table[*code-'a']=next;
cur=next;
}

++code;
}

if(cur!=&tree->root)
{
if(cur->name.count(name)!=0)
{
return false;
}

cur->name.insert(name);
return true;
}
else
{
return false;
}
}

Node* find(const char *code,Trie *tree)
{
Node *cur=&tree->root;

while(*code!=0)
{
if(cur->table[*code-'a']!=NULL)
{
cur=cur->table[*code-'a'];
}
else
{
return NULL;
}

++code;
}

if(cur!=&tree->root)
{
return cur;
}
else
{
return NULL;
}
}

void update(const char *code,Trie *tree)
{
Node *p=find(code,tree);

if(p)
{
queue<Node*> q;

q.push(p);

while(!q.empty())
{
Node *head=q.front();
q.pop();

for(set<string>::iterator iter=head->name.begin();iter!=head->name.end();++iter)
{
cout<<*iter<<endl;
}

for(int i=0;i<26;++i)
{
if(head->table[i]!=NULL)
{
q.push(head->table[i]);
}
}
}
}
}

int main()
{
Trie *tree=createTrie();
insert("liangdong","梁栋",tree);
insert("liangshen","梁神",tree);

char buffer[100]={0};
int i=0;

while(true)
{
while( (buffer[i++]=getchar())!='\n' )
{
}

if(buffer[i-1]==EOF)
{
break;
}

buffer[--i]=0;
system("cls");
cout<<buffer<<endl;
update(buffer,tree);
fflush(stdin);
}

return 0;
}



给你个简单例子,用我给的两个例子做测试即可。
qq120848369 2011-03-23
  • 打赏
  • 举报
回复
搜索:Trie树,可以极大的满足你。
tangsun1227 2011-03-23
  • 打赏
  • 举报
回复
算法珠玑里第一个例子
紫色动力 2011-03-23
  • 打赏
  • 举报
回复
输入第二个字母时再从第一次查找的结果中查找?以此类推?
紫色动力 2011-03-23
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wuyu637 的回复:]
最简单,最裸的办法就是一个一个查找了。
因为通常来说电话本的数据量不会太大,几百的量级,

根据输入的字母,从电话簿的第一个名字开始查找,符合拼音就输出,不符合就跳过查找下一个。
[/Quote]
第输入一个字母就查一遍吗?
匚匚 2011-03-23
  • 打赏
  • 举报
回复
/*编程建立一通讯簿,存放有姓名、电话号码、住址,然后对通信簿进行查找、添加、修改及删除。*/
#include<stdio.h>
struct person
{
char name[8];
char tel[15];
char addr[50];
};

char filename[20];
FILE *fp;

void creat();
void output();
void search();
void append();
void modify();
void delete();

main()
{
int m;

creat();
while(1)
{
printf("\n\n添加,请按1");
printf("\n查找,请按2");
printf("\n修改,请按3");
printf("\n删除,请按4");
printf("\n输出,请按5");
printf("\n退出,请按0\n");
scanf("%d",&m);
if(m>=0&&m<=5)
{
switch(m)
{
case 1: append();
break;
case 2: search();
break;
case 3: modify();
break;
case 4: delete();
break;
case 5: output();
break;
case 0: exit();
}
printf("\n\n操作完毕,请再次选择!");
}
else
printf("\n\n选择错误,请再次选择!");
}
}


void creat()
{
struct person one;
long s1;

printf("\n请输入通讯簿名:");
scanf("%s",filename);
if((fp=fopen(filename,"w"))==NULL)
{
printf("\n不能建立通讯簿!");
exit();
}
fprintf(fp,"%-10s%-20s%-50s\n","姓名","电话号码","住址");
printf("\n请输入姓名、电话号码及住址(以0结束)\n");
scanf("%s",one.name);
while(strcmp(one.name,"0"))
{
scanf("%s%s",one.tel,one.addr);
fprintf(fp,"%-10s%-20s%-50s\n",one.name,one.tel,one.addr);
scanf("%s",one.name);
}
fclose(fp);
}

void output()
{
struct person one;

if((fp=fopen(filename,"r"))==NULL)
{
printf("\n不能打开通讯簿!");
exit();
}
printf("\n\n%20s\n","通 讯 簿");
while(!feof(fp))
{
fscanf(fp,"%s%s%s\n",one.name,one.tel,one.addr);
printf("%-10s%-20s%-50s",one.name,one.tel,one.addr);
}
fclose(fp);
}

void append()
{
struct person one;

if((fp=fopen(filename,"a"))==NULL)
{
printf("\n不能打开通讯簿!");
exit();
}
printf("\n请输入添加的姓名、电话号码及住址\n");
scanf("%s%s%s",one.name,one.tel,one.addr);
fprintf(fp,"%-10s%-20s%-50s\n",one.name,one.tel,one.addr);
fclose(fp);
}

void search()
{
int k=0;
char namekey[8];
struct person one;

printf("\n请输入姓名:");
scanf("%s",namekey);

if((fp=fopen(filename,"rb"))==NULL)
{
printf("\n不能打开通讯簿!");
exit();
}
while(!feof(fp))
{
fscanf(fp,"%s%s%s\n",one.name,one.tel,one.addr);
if(!strcmp(namekey,one.name))
{
printf("\n\n已查到,记录为:");
printf("\n%-10s%-18s%-50s",one.name,one.tel,one.addr);
k=1;
}
}
if(!k)
printf("\n\n对不起,通讯簿中没有此人的记录。");
fclose(fp);
}

void modify()
{
int m,k=0;
long offset;
char namekey[8];
struct person one;

printf("\n请输入姓名:");
scanf("%s",namekey);

if((fp=fopen(filename,"r+"))==NULL)
{
printf("\n不能打开通讯簿!");
exit();
}
while(!feof(fp))
{
offset=ftell(fp);
fscanf(fp,"%s%s%s\n",one.name,one.tel,one.addr);
if(!strcmp(namekey,one.name))
{
k=1;
break;
}
}
if(k)
{
printf("\n已查到,记录为:");
printf("\n%-10s%-18s%-50s",one.name,one.tel,one.addr);
printf("\n请输入新姓名、电话号码及住址:");
scanf("%s%s%s",one.name,one.tel,one.addr);
fseek(fp,offset,SEEK_SET);
printf("%ld",ftell(fp));
fprintf(fp,"%-10s%-20s%-50s\n",one.name,one.tel,one.addr);
}
else
printf("\n对不起,通讯簿中没有此人的记录。");
fclose(fp);
}

void delete()
{
int m,k=0,flag;
long offset1,offset2;
char namekey[8], valid[4];
struct person one;

printf("\n请输入姓名:");
scanf("%s",namekey);
if((fp=fopen(filename,"r+"))==NULL)
{
printf("\n不能打开通讯簿!");
exit();
}
while(!feof(fp))
{
offset1=ftell(fp);
fscanf(fp,"%s%s%s\n",one.name,one.tel,one.addr);
if(!strcmp(namekey,one.name))
{
k=1;
break;
}
}
if(k)
{
printf("\n已查到,记录为");
printf("\n%-10s%-18s%-50s",one.name,one.tel,one.addr);
printf("\n确实要删除,按1;不删除,按0:");
scanf("%d",&m);
if(m)
{
fseek(fp,offset1,SEEK_SET);
fprintf(fp,"%-10s%-20s%-50s\n","","","");
}
}
else
printf("\n对不起,通讯簿中没有此人的记录。");
fclose(fp);
}

wei801516 2011-03-23
  • 打赏
  • 举报
回复
键值对哦。。。。map容器就可以了
pmars 2011-03-23
  • 打赏
  • 举报
回复
算法真的不用那么复杂,直接找就行了,数据量挺小的,只是功能上下功夫就好了吧!
wuyu637 2011-03-23
  • 打赏
  • 举报
回复
最简单,最裸的办法就是一个一个查找了。
因为通常来说电话本的数据量不会太大,几百的量级,

根据输入的字母,从电话簿的第一个名字开始查找,符合拼音就输出,不符合就跳过查找下一个。
附训练好的 YOLO 权重与 PyQt 可视化检测界面,页面底部含可视化效果预览,毕设/课设开箱即用。 【数据集概况】 · 检测类别(中文):[领航车(leader)] · 训练集:414 张 · 验证集:39 张 · 测试集:20 张 · 总计:473 张 该数据集聚焦于室内走廊环境中对领航车的精准识别与定位,具备高度场景专一性与实际应用价值。图像采集于光线均匀、结构规整的建筑内部通道,背景干扰因素少,有利于模型在复杂环境下的目标提取能力训练。领航车作为核心检测对象,在不同距离和角度下均被清晰标注,为智能导航系统、自动化引导设备等提供可靠的数据支持。... 【训练曲线与评估图】 【模型训练配置】 参数 | 值 模型 | yolo26n 训练轮数 | 100 epochs 输入尺寸 | 640x640 批次大小 | 24 优化器 | auto 初始学习率 | 0.01 训练设备 【关键指标汇总】 训练了 77 个 epoch,最终轮指标: 指标 | 数值 mAP50 | **0.9950** mAP50-95 | 0.9141 Precision | 0.9985 Recall | 1.0000 train/box_loss | 0.5224 train/cls_loss | 0.2526 val/box_loss | 0.4307 val/cls_loss | 0.1407 【训练过程分析】 77 轮训练后 mAP50 达到 0.9950,模型收敛良好。Loss 曲线前段快速下降,后段趋于平稳,val_loss 无反弹,没有明显过拟合。mAP50-95 为 0.9141,和 mAP50 差距仅 0.08,框的定位精度也很扎实。 【模型性能评估】 Precision 0.9985、Recall 1.000... 使用场景:毕业设计、课程设计、深度学习入门、工业场景落地验证。
内容概要:本文围绕基于序贯蒙特卡洛模拟法的配电网可靠性评估展开深入研究,提出并实现了结合Matlab的仿真方法,用于精确评估配电网在多种故障场景下的供电可靠性。研究充分考虑了元件故障、时序恢复过程及系统运行的随机性与动态性,采用序贯抽样技术模拟系统状态转移过程,实现了对停电频率、停电时间、供电可用率等关键可靠性指标的量化分析。文中系统阐述了算法的设计流程、事件抽样机制、状态序列生成逻辑以及系统恢复策略,并通过典型算例验证了该方法在复杂配电网络中的有效性与实用性,为配电网的规划、运行与优化提供了科学的评估工具。; 适合人群:具备电力系统分析基础和Matlab编程能力的高校研究生、科研人员,以及从事配电网规划设计、运行维护与可靠性管理的工程技术人员。; 使用场景及目标:①掌握序贯蒙特卡洛模拟法在电力系统可靠性评估中的核心原理与实现方法;②学习利用Matlab构建配电网时序仿真模型,进行可靠性指标计算与分析;③为配电网的设备选型、网络结构优化、故障应对策略制定及韧性提升提供数据支撑与决策依据; 阅读建议:建议读者结合文中提供的Matlab代码实现步骤,动手复现实验过程,深入理解状态抽样、时序序列模拟、故障处理逻辑与指标统计等关键环节,并可进一步将该方法拓展应用于含分布式电源、储能系统等新型元件的现代复杂配电网可靠性评估研究。

65,214

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧