超长字符串

超长数字串


【问题描述】

给一个数字串 STR:123456789101112131415161718192021222324......它是由所有自然数从小到大依次排列起来的。任意给一个数字串 T,容易知道它一定在 STR 中出现无穷多次。现要求任意给一个数字 n 作为串 T,并按上述规则将从

1~n 的所有数字连续串在一起组成一个完整的串 S。求出串 T 在串 S 中所有出现

的位置。

例如,若 n=81,则从 1 到 81 的所有自然数连在一起构成串 S,而“81”首

次出现的位置为 27.你的任务是找出此串中“81”出现的所有位置和出现次数。最后给出一份列表,列出 n 从 1 到 100 时,所有字符串值为 n 的出现首位置和次数。

【基本要求】

1.输入 n 值后首先计算出串 S 的长度 L,计算公式的理论推导自行完成

(1<n<1000)。

2.串 S 的存储采用动态内存分配方式,并且要求将串指针和串长变量封装在一起(用结构体)。

3.程序要求实现两个功能(可通过按键选择实现):

其一为能够接受从键盘上输入的 n 值,并以此为依据生成串 S,然后输出串值为 n 的子串在 S 中出现的所有位置和次数。

其二为通过循环计算出 n 从 1 到 100 时,所有字符串值为 n 的出现首位置和次数,并将结果存储在一个文本文件中。

【输入输出】

对于第一个功能,输入输出形式为:输入数据:输入数值 n:12

输出数据:在从 1 到 12 所构成的串中,12 出现的位置分别是:1,14.共

出现 2 次。

对于第二个功能,输出形式为:

n 出现首位置出现次数

111

221

............

21152



代码如下:

#include<windows.h>
#include<stdio.h>
#include<iostream>
#include<fstream>
#include <sstream>
#include<string>
using namespace std;


typedef struct _MyInfo
{
	int      nNum;
	char*   str;

	//构造函数必须写上
	_MyInfo() {
		nNum = 0;
		str = NULL;
	}
} INFO;



//选项菜单
int menue()
{
	int num;
	char ch;
	printf("\t================\n");
	printf("\t1.输入n值执行\n");
	printf("\t2.输出到文本\n");
	printf("\t3.退出\n");
	cin >> num;
	while ( num>3|| num<1)
	{
		while (ch = getchar() != '\n');
		printf("请输入选择: 1/2 \n");
	}
	return num;
}


//功能:输入的n,统计位数
int totalbyte(int n) {
	
	int sumbyte = 0;
	for (int i = 1; i <= n; i++)
	{
		if ((i / 1000) != 0) { sumbyte = sumbyte + 4; }//千
		
		else {
			if ((i / 100) != 0){sumbyte = sumbyte + 3;}//百

			else {

				if((i / 10) != 0){ sumbyte = sumbyte + 2; }//十

				else { sumbyte = sumbyte + 1; }	//个				
			}
		}
		
	}
	
	return sumbyte;
}



//功能:输入的n,生成字符串
string InAddtoString(int n) {
	string result = "";
	ostringstream oss;
	for (int i = 1; i <= n; i++)
	{
		oss << i;
	}
	result += oss.str();
	cout << result<<endl;
	return result;
}


//功能:输入的n,生成字符串
char* CreatStr(char* m_str,int n) {
	
	for (int i = 1; i <= n; i++)
	{
		sprintf(m_str, "%s%d", m_str,i);
		
	}
	//cout << "字符串长度:" << strlen(m_str) << endl;
	return m_str;
}



//功能:输入的n,定位第一次位置,输出信息
void OutFirstlocation(char* str,char* substr, ofstream &ofs,int n,char* outbuff){
	
	char *p = str, *q = substr;
	char*p1 = NULL;

	int flag = 0;
	for (int i=1; *(p + strlen(substr) - 1); p++,i++)
	{
		p1 = p;
		for (q = substr; *p1 == *q&&*q; p1++, q++);
		if (!*q)
		{
			flag++;
			if (flag == 1)
			{
				sprintf(outbuff, "%d%s%d", n,"首次出现在:", i);
				ofs << outbuff << endl;
			}
			//cout <<"第"<<flag++<<"次出现的位置:" << i<<endl;
		}
	}
	p = NULL;
	q = NULL;

}

//功能:输入的n,定位所有的位置
void Getlocation(char* str, char* substr) {

	char *p = str, *q = substr;
	char*p1 = NULL;

	int flag = 0;
	for (int i = 1; *(p + strlen(substr) - 1); p++, i++)
	{
		p1 = p;
		for (q = substr; *p1 == *q&&*q; p1++, q++);
		if (!*q)
		{
			flag++;
			cout << "第" << flag<< "次出现的位置:" << i << endl;
		}
	}
	p = NULL;
	q = NULL;
	cout << "共出现次数:" << flag << endl;
}


//功能:获取键盘输入的n,生成字符串,输出n的位置
void Function1() {
	int n;
	cout << "输入某个自然数:";
	cin >> n;
	int num = totalbyte(n);
	cout << "总位数" << num << endl;
	char* m_str = new char[num + 1];
	memset(m_str, 0, num + 1); 

	m_str =CreatStr(m_str,n);
	char my_substr[5] = { 0 };
	sprintf(my_substr, "%d", n);
	Getlocation(m_str, my_substr);

	
	delete m_str;
	m_str = NULL;
}

//功能:n从1-1000,处理结果输出到文件
void Function2() {

	//若不存在文件,会创建文件
	ofstream ofresult;
	ofresult.open("result.txt", ios::out );
	ofresult << "=====================" << endl;

	char outbuff[30] = { 0 };
	char my_substr[5] = { 0 };
	for (int n = 1; n <= 100; n++) {

		memset(outbuff,0,sizeof(outbuff));
		int num = totalbyte(n);
		//cout << "总位数" << num << endl;
		char* m_str = new char[num + 1];
		memset(m_str, 0, num + 1);
		m_str = CreatStr(m_str, n);

		memset(my_substr, 0, sizeof(my_substr));
		sprintf(my_substr, "%d", n);
		OutFirstlocation(m_str, my_substr, ofresult,n, outbuff);

		delete m_str;
		m_str = NULL;
	}
	ofresult << "=====================" << endl;
	ofresult.close();
	cout << "已保存到文本" << endl;
}

void main() {

	system("cls");
	BOOL RunFlag=TRUE;
 
	while (RunFlag)
	{
		switch (menue())	//登陆主界面操作
		{
		case 1:Function1(); break;
		case 2:Function2(); break;
		case 3: {RunFlag = FALSE; }; break;
		}
	}
	system("pause");

}

//void main() {
//	//Function1();
//	Function2();
//	system("pause");
//}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值