从Fibonacci数列规律补齐电话号码
1.问题分析
[Index, NAME, Gender, PhoneNumber]
[1, “肖战”, “男”, “13700832040”]
[2, “钟汉良”, “男”, “13601346269”]
[3, “吴映洁”, “女”, “13902178309”]
[4, “赵丽颖”, “女”, “13503524578”]
[5, “胡歌”, “男”, “13205702887”]
[6, “迪丽热巴”, “女”, “13809227465”]
[7, “景甜”, “女”, “13114930352”]
[8, “祁东”, “男”, “13024157817”]
[9, “王珞丹”, “女”, “135********”]
- 打印Fibonacci前40项。
- 根据上表中PhoneNumber规律及Fibonacci补齐"王珞丹"的PhoneNumber。
- 请以PhoneNumber为排序选项对上表进行升序排序。
2.设计思路
根据Fibonacci数列规律,实现该数列的打印,这里可输入一个参数,用来实现动态打印Fibonacci数列的前n项。
补齐电话号码编程思路:
- 结构体数组输入表的信息/或从txt文本读入表的信息
- 将PhoneNumber前三位和后八位分割,将后八位从strin/char*转换为int型
- 得到“王珞丹”的电话号码后八位,从int型转换为char*/string,使用strcat()函数连接
- 打印王珞丹项的信息
3.知识点解析
Fibonacci数列的规律公式为
字符串截取可使用==substr()==函数,包含在头文件中,substr()函数的使用有两种形式。
形式一:substr(pos,n)
注释:1.pos表示截取字符的下标。
2.n代表从截取pos之后的n个字符。
形式二:substr(n)
注释:1.若n>=0,表示截取从下标为n后的所有字符。
2.若n<0,表示截取字符串倒数第n个后的所有字符。
注意点:
eg:
string a="abcdef";
if(a.substr(2,1)=="c")注意 ==后面的不管是一个字符还是字符串都要带上“”,即带上双引号。
cout<<-1;
C++中string转int
方法一:使用atoi()函数
函数原型:int atoi(const char *nptr);
函数说明:
atoi( ) 函数会扫描参数 nptr字符串,跳过前面的空白字符(例如空格,tab缩进等,可以通过isspace( )函数来检测),直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时(‘\0’)才结束转换,并将结果返回。如果 nptr不能转换成 int 或者 nptr为空字符串,那么将返回 0。
C++中若需要将string类型转为int类型,需先将string转为const char*。
函数原型:
const char *c_str();
函数说明:
c_str()函数返回一个指向正规C字符串的指针常量, 内容与本string串相同.这是为了与c语言兼容,在c语言中没有string类型,故必须通过string类对象的成员函数c_str()把string 对象转换成c中的字符串样式。
注意:一定要使用strcpy()函数 等来操作方法c_str()返回的指针
比如:最好不要这样:
char* c;
string s="1234";
c = s.c_str(); //c最后指向的内容是垃圾,因为s对象被析构,其内容被处理,同时,编译器也将报错——将一个const char *赋与一个char *。
应该这样用:
char c[20];
string s="1234";
strcpy(c,s.c_str());
这样才不会出错,c_str()返回的是一个临时指针,不能对其进行操作
再举个例子
c_str() 以 char* 形式传回 string 内含字符串
如果一个函数要求char*参数,可以使用c_str()方法:
string s = "Hello World!";
printf("%s", s.c_str()); //输出 "Hello World!"
例:
#include <iostream>
#include <string>
using namespace std;
int main()
{
char* s = "1234";
string str("5678");
int intS = atoi(s);
//此写法会报错
//int intStr = atoi(str);
//需先将string转成char*
int intStr = atoi(str.c_str());
cout << "char* 转int: " << intS << endl;
cout << "string 转int: " << intStr << endl;
system("pause");
return 0;
}
方法二:使用stringstream
C++中将形如"1234"的string字符串转化为int型整数”里所介绍的方法其实是将string字符串先转换为C风格的字符串,再利用C语言提供的库函数atoi将字符串转换为整型数。
这种方法严格来说不是C++的做法,因为C++本身就提供了字符串与整型数之间的互换,那就是利用stringstream。下面是使用方法:
#include <iostream>
#include <string>
#include <sstream> //要使用stringstream流应包含此头文件
using namespace std;
int main()
{
stringstream stream; //声明一个stringstream变量
int n;
string str;
//string转int
stream << "1234"; //向stream中插入字符串"1234"
stream >> n; //从stream中提取刚插入的字符串"1234"
//并将其赋予变量n完成字符串到int的转换
cout <<"stringstream string转int: "<< n << endl; //输出n
stream.clear(); //同一stream进行多次转换应调用成员函数clear
//int转string
stream << 1234; //向stream中插入整型数1234
stream >> str; //从steam中提取刚插入的整型数
//并将其赋予变量str完成整型数到string的转换
cout << "stringstream int转string: " << str << endl; //输出str
system("pause");
return 0;
}
4.代码
Fibonacci.cpp:
// Fibonacci.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include<iostream>
#include<fstream>
#include<iomanip>
#include<string>
#include<algorithm>
#include<sstream>
using namespace std;
struct PersonList
{
int index;
char name[20];
char gender[10];
char PhoneNumber[20];
};
const int currentN = 9;
//根据任务内容为结构体赋值
PersonList* init()
{
// PersonList person[12];
PersonList* person = new PersonList[currentN];
person[0] = { 1, "肖战", "男", "13700832040" };
person[1] = { 2, "钟汉良", "男", "13601346269" };
person[2] = { 3, "吴映洁", "女", "13902178309" };
person[3] = { 4, "赵丽颖", "女", "13503524578" };
person[4] = { 5, "胡歌", "男", "13205702887" };
person[5] = { 6, "迪丽热巴", "女", "13809227465" };
person[6] = { 7, "景甜", "女", "13114930352" };
person[7] = { 8, "祁东", "男", "13024157817" };
person[8] = { 9, "王珞丹", "女", "135********" };
return person;
}
//打印结构体数组表
void display(PersonList *person)
{
cout << "index " << "\t\t" << "NAME" << "\t\t" << "Gender" << "\t\t" <<" PhoneNumber" << endl;
for (int i = 0; i < currentN; i++)
{
cout << person[i].index << "\t\t" << person[i].name << "\t\t" << person[i].gender << "\t\t" << person[i].PhoneNumber << endl;
}
}
//获取fibonacci并打印
void generate(int n)
{
int a = 0;
int b = 1;
int c;
cout << a << " " << b;
for (int i = 1; i <= n - 2; i++) {
c = a + b; cout << " " << c;
a = b;
b = c;
}
}
// 计算"王珞丹"的电话号码后八位
int calculationPhone(PersonList* person)
{
stringstream stream;
int s = 0;
int m, n;
string s1 = person[6].PhoneNumber;
string s2 = person[7].PhoneNumber;
string str1 = s1.substr(3, 8);
string str2 = s2.substr(3, 8);
//cout << str1 << endl;
//cout << str2 << endl;
stream << str1;
stream >> m;
stream.clear();
stream << str2;
stream >> n;
s = m + n;
cout << "根据表中PhoneNumber規律及Fibonacci规律总结出,电话号码后八位符合Fibonacci数列规律,F(n) = F(n-1)+F(n-2)" << endl;
cout << "序号为7的电话号码后八位是: " << m << endl;
cout << "序号为8的电话号码后八位是: " << n << endl;
cout << "王珞丹的电话号码后八位计算结果为: " << s << endl;
return s;
}
//补齐"王珞丹"电话号码
void modifyPhone(PersonList* person,int n)
{
int num = n;
stringstream stream;
//PersonList* human = init();
//int num = calculationPhone(human);//调用能够实现,这里是功能函数,故使用传参形式调用
string str2;
string str = person[8].PhoneNumber;
string s1 = str.substr(0, 3);//截取前三位
stream << num;
stream >> str2;
// string str3 = strcat(s1.c_str, str2.c_str);
string str3 = s1 + str2;
cout <<"王珞丹的电话号码为:" << str3 << endl;
strcpy_s(person[8].PhoneNumber, str3.c_str());
int i = 8;
cout << "补齐后王珞丹的信息输出如下:" << endl;
cout << "index " << "\t\t" << "NAME" << "\t\t" << "Gender" << "\t\t" << " PhoneNumber" << endl;
cout << person[i].index << "\t\t" << person[i].name << "\t\t" << person[i].gender << "\t\t" << person[i].PhoneNumber << endl;
}
//插入排序,按照PhoneNumber排序(升序)
void InsertionSort(PersonList* person)
{
for (int i = 1; i < currentN; ++i)
{
for (int j = 0; j < i; ++j)
{
if (strcmp(person[j].PhoneNumber, person[i].PhoneNumber) > 0)
{
PersonList temp = person[i];//这样的话,根据电话号码,调整电话号码所在对象的位置,整个对象 都会随着号码的升序而跟着改变
for (int k = i; k > j; --k)
person[k] = person[k - 1];
person[j] = temp;
}
}
}
}
void showhelp()
{
cout << "根据菜单栏提示,输入对应功能,即可实现对本系统操作" << endl;
}
void menu()
{
cout << "--------------------------------------------" << endl;
cout << "欢迎使用本系统" << endl;
cout << "0:showhelp" << endl;
cout << "1:打印Fibonacci数列" << endl;
cout << "2:补全'王珞丹'电话号码" << endl;
cout << "3:根据PhoneNumber排序" << endl;
cout << "4:退出系统" << endl;
cout << "\n";
}
int main(int argc, char* argv[])
{
//if (argc == 2)
//{
PersonList* human = init();
while (1)
{
menu();
int choose;
cout << "请输入您需要功能的数字:" << endl;
cin >> choose;
if (choose == 0)
{
showhelp();
system("pause");
// return -1;
}
else if (choose == 1)
{
//fibonacci数组打印测试
cout << "Hello world! Fibonacci series" << endl;
cout << "Enter number of items you need in the series: ";
int n;
cin >> n;
generate(n);
system("pause");
//return -1;
}
else if (choose == 2)
{
//测试计算机“王珞丹”电话号码
//PersonList* human = init();
int n = calculationPhone(human);
//calculationPhone(human);
modifyPhone(human, n);
//display(human);
system("pause");
// return -1;
}
else if (choose == 3)
{
//排序测试
//PersonList* human = init();
cout << "排序前" << endl;
display(human);
InsertionSort(human);
cout << "排序后" << endl;
display(human);
system("pause");
//return -1;
}
else if (choose == 4)
{
system("cls");
system("pause");
return -1;
}
else
{
cout << "输入错误,请重新输入" << endl;
cout << "\n";
showhelp();
continue;
}
}
//}
system("cls");
//system("pause");
return -1;
}
5.运行结果
Fibonacci数列打印:
补齐电话号码:
排序:
这里可以看到‘迪丽热巴’没有对齐,这是因为一个汉字是两个字节,字符串数组是以‘\0’结尾,占用9个字节,由于使用visual studio工具,默认字节对齐数为8,所以这里在对齐时,“”迪丽热巴“占用的的大小是9+7 = 16B,最后导致没有对齐,对这点模糊的读者可在”迪丽热巴“后补字数,会发现,在补1-3个数的时候,对齐是不变的,但是添加道第四个字后,对齐又会发生改变。
看到这里就结束了,希望今天仍然美好。