超长数字串
【问题描述】
给一个数字串 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");
//}