从Fibonacci数列规律补齐电话号码

从Fibonacci数列规律补齐电话号码

1.问题分析

[Index, NAME, Gender, PhoneNumber]
[1, “肖战”, “男”, “13700832040”]
[2, “钟汉良”, “男”, “13601346269”]
[3, “吴映洁”, “女”, “13902178309”]
[4, “赵丽颖”, “女”, “13503524578”]
[5, “胡歌”, “男”, “13205702887”]
[6, “迪丽热巴”, “女”, “13809227465”]
[7, “景甜”, “女”, “13114930352”]
[8, “祁东”, “男”, “13024157817”]
[9, “王珞丹”, “女”, “135********”]

  1. 打印Fibonacci前40项。
  2. 根据上表中PhoneNumber规律及Fibonacci补齐"王珞丹"的PhoneNumber。
  3. 请以PhoneNumber为排序选项对上表进行升序排序。

2.设计思路

根据Fibonacci数列规律,实现该数列的打印,这里可输入一个参数,用来实现动态打印Fibonacci数列的前n项。

补齐电话号码编程思路:

  1. 结构体数组输入表的信息/或从txt文本读入表的信息
  2. 将PhoneNumber前三位和后八位分割,将后八位从strin/char*转换为int型
  3. 得到“王珞丹”的电话号码后八位,从int型转换为char*/string,使用strcat()函数连接
  4. 打印王珞丹项的信息

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个数的时候,对齐是不变的,但是添加道第四个字后,对齐又会发生改变。

看到这里就结束了,希望今天仍然美好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值