输入任意正整数,输出比这个数大的最小不重复数(相邻两个数字不重复),例如1101是重复,1234不重复,1201不重复,下面这个代码针对这道题,出了错不懂哪里的,求解
#include <iostream>
//#include <malloc.h>
using namespace std;
class GetDiffNum
{
int temp; //输入数字
int a[10]; //输入数字n的数字表示a[]
int length; //输入数字的位数,数组a[]的有效位数
public:
GetDiffNum(){ temp = 0; a[0] = 0; a[1] = '\0'; }
GetDiffNum(int n);
~GetDiffNum(){}
void GetTheArrayDisp();
void GetTheNumDisp();
int GetThePlace();
int GetTheNum();
};
GetDiffNum::GetDiffNum(int n)
{
temp = n; //输入数字赋值给类的私有变量temp
}
void GetDiffNum::GetTheArrayDisp() //获得输入数字n的数字表示a[]和有效位数length
{
int b[10], i, j;
i = 0;
j = 0;
while (temp % 10 != 0)
{
b[i++] = temp % 10;
temp = temp / 10;
}
length = i; //length为数组有效位数
i--;
while (i >= 0)
a[j++] = b[i--];
a[j] = '\0';
}
void GetDiffNum::GetTheNumDisp()
{
int i = 0, sum = 0;
while (a[i] != '\0')
{
sum *= 10;
sum += a[i];
i++;
}
temp = sum;
}
int GetDiffNum::GetThePlace() //如果输入数字重复,返回输入数字n中相邻位置数字重复的第二个数字的数组表示位置 //如果输入数字不重复,返回0
{
if (a[0] == '\0')
return 0;
int i;
for (i = 0; a[i+1] != '\0';i++)
if (a[i] == a[i + 1])
return i + 1;
return 0;
}
int GetDiffNum::GetTheNum() //获得比输入数字n大的不重复数字
{
int k,h,m,i,s,mom;
s = 0;
mom = 1;
GetTheArrayDisp();
k = GetThePlace();
if (k < 0)
return -1; //错误,k>=0,基本不考虑
m = k;
h = k;
if (k == 0) //输入数字不重复
{
temp += 1;
GetTheArrayDisp();
h = GetThePlace();
if (h == 0)
return temp;
}
a[h] += 1;
GetTheNumDisp();
GetTheArrayDisp();
h = GetThePlace();
if (h == 0)
m = k;
else
{
while (h <= m&&h != 0)
{
m = h;
a[h] += 1;
GetTheNumDisp();
GetTheArrayDisp();
h = GetThePlace();
}
}
for (i = m + 1; i < length; i++)
{
if (a[m] == 0)
{
s += mom;
mom = -mom;
a[i] = s;
}
else
{
a[i] = s;
s += mom;
mom = -mom;
}
}
GetTheNumDisp();
return temp;
}
void main()
{
GetDiffNum Ln(1989);
int betternum;
betternum = Ln.GetTheNum();
cout << betternum << endl;
}
最简单的办法,+1 循环,检测是否不重复,是则结束。
至于算法嘛,说真的,在非技术流(算法流)开发中,商业开发还是基于开发效率考虑,除非这个简单的算法在系统中对性能的影响很大甚至成为瓶颈时才考虑。
当然,这个是考试题,另当别论。应聘遇到这样的题目,那也是绝对高级了,在腾讯,至少要20K的待遇吧?而且,即便是牛人,除非专攻算法领域或接触过的,这个题目至少半小时甚至更多时间才能解答出来吧?
刚分析你的代码,有点乱,不想看,我给出我写的代码:
1 #include "stdafx.h" 2 #include <iostream> 3 //#include <malloc.h> 4 using namespace std; 5 6 class FirstBigUnrepeatData 7 { 8 private: 9 int _initValue; //原始数据 10 int _currentValue;//当前数据 11 int _bitArray[10]; //当前数据的数组表现形式 12 int _dataLength; //_bitArray的位数 13 private: 14 void InitBitArray(); 15 int GetTheFirstRepeatIndex(); 16 void IncreaseData(int index); 17 void GenerateNewData(); 18 public: 19 FirstBigUnrepeatData(){ _initValue = _currentValue = 0; _bitArray[0] = 0; _bitArray[1] = '\0'; } 20 FirstBigUnrepeatData(int value); 21 ~FirstBigUnrepeatData(){} 22 int GetResult(); 23 }; 24 25 FirstBigUnrepeatData::FirstBigUnrepeatData(int value) 26 { 27 _initValue = value; //输入数字赋值给类的私有变量temp 28 _currentValue = _initValue + 1; 29 _dataLength = 0; 30 } 31 32 void FirstBigUnrepeatData::InitBitArray() //获得输入数字n的数字表示a[]和有效位数length 33 { 34 int b[10]; 35 int temp = _currentValue; 36 _dataLength = 0; 37 while (temp != 0) 38 { 39 b[_dataLength++] = temp % 10; 40 temp = temp / 10; 41 } 42 int i = _dataLength; 43 while (i > 0) 44 { 45 _bitArray[_dataLength - i] = b[i - 1]; 46 i--; 47 } 48 } 49 50 void FirstBigUnrepeatData::GenerateNewData() 51 { 52 _currentValue = 0; 53 for (int i = 0; i < _dataLength; i++) 54 { 55 _currentValue *= 10; 56 _currentValue += _bitArray[i]; 57 } 58 } 59 60 void FirstBigUnrepeatData::IncreaseData(int index) 61 { 62 int bit = _bitArray[index]; 63 bit++; 64 _bitArray[index] = bit % 10; 65 if (bit > 9) 66 { 67 if (index > 0) 68 { 69 IncreaseData(index - 1); 70 } 71 else 72 { 73 for (int i = _dataLength; i > 0; i--) 74 { 75 _bitArray[i] = _bitArray[i - 1]; 76 } 77 _bitArray[0] = 1; 78 } 79 } 80 } 81 82 int FirstBigUnrepeatData::GetTheFirstRepeatIndex() //如果输入数字重复,返回输入数字n中相邻位置数字重复的第二个数字的数组表示位置 //如果输入数字不重复,返回0 83 { 84 for (int i = 0; i < _dataLength - 1; i++) 85 { 86 for (int j = i + 1; j < _dataLength; j++) 87 { 88 if (_bitArray[i] == _bitArray[j]) 89 { 90 return j; 91 } 92 } 93 } 94 return -1; 95 } 96 97 int FirstBigUnrepeatData::GetResult() //获得比输入数字n大的不重复数字 98 { 99 while (true) 100 { 101 InitBitArray(); 102 int index = GetTheFirstRepeatIndex(); 103 if (index <= 0) 104 { 105 return _currentValue; 106 } 107 IncreaseData(index); 108 GenerateNewData(); 109 } 110 } 111 112 void main() 113 { 114 FirstBigUnrepeatData Ln(1989); 115 int betternum; 116 betternum = Ln.GetResult(); 117 cout << betternum << endl; 118 }
在你的代码中,语句:while (temp % 10 != 0) 是不对的,应该更改为:
while (temp != 0)
其它地方的代码没细看了。
再给你一个结果:
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> //#include <malloc.h> using namespace std; class FirstBigUnrepeatData { private: int _initValue; //原始数据 int _currentValue;//当前数据 int _bitArray[10]; //当前数据的数组表现形式 int _dataLength; //_bitArray的位数 bool _calced; private: FirstBigUnrepeatData *_next; private: void InitBitArray(); int GetTheFirstRepeatIndex(); void IncreaseData(int index); void GenerateNewData(); void Calc(); public: FirstBigUnrepeatData() { this->_initValue = this->_currentValue = 0; this->_dataLength = 0; this->_calced = false; this->_next = NULL; } FirstBigUnrepeatData(int value); ~FirstBigUnrepeatData() { if (this->_next != NULL) { delete this->_next; this->_next = NULL; } } int GetValue(); FirstBigUnrepeatData * Next(); int NextValue(); public: static FirstBigUnrepeatData* Create(int value); }; FirstBigUnrepeatData *FirstBigUnrepeatData::Create(int value) { return new FirstBigUnrepeatData(value); } FirstBigUnrepeatData *FirstBigUnrepeatData::Next() { if (this->_next == NULL) { if (!this->_calced) { this->Calc(); } int value = this->_currentValue; this->_next = new FirstBigUnrepeatData(value); } return this->_next; } int FirstBigUnrepeatData::GetValue() { if (_calced == false) { Calc(); } return this->_currentValue; } int FirstBigUnrepeatData::NextValue() { FirstBigUnrepeatData *next = this->Next(); return next->GetValue(); } FirstBigUnrepeatData::FirstBigUnrepeatData(int value) :FirstBigUnrepeatData() { this->_initValue = value; //输入数字赋值给类的私有变量temp this->_currentValue = this->_initValue + 1; this->_dataLength = 0; } void FirstBigUnrepeatData::InitBitArray() //获得输入数字n的数字表示a[]和有效位数length { int b[10]; int temp = this->_currentValue; this->_dataLength = 0; while (temp != 0) { b[this->_dataLength++] = temp % 10; temp = temp / 10; } int i = this->_dataLength; while (i > 0) { this->_bitArray[this->_dataLength - i] = b[i - 1]; i--; } } void FirstBigUnrepeatData::GenerateNewData() { this->_currentValue = 0; for (int i = 0; i < this->_dataLength; i++) { this->_currentValue *= 10; this->_currentValue += this->_bitArray[i]; } } void FirstBigUnrepeatData::IncreaseData(int index) { int bit = this->_bitArray[index]; bit++; this->_bitArray[index] = bit % 10; if (bit > 9) { if (index > 0) { this->IncreaseData(index - 1); } else { for (int i = this->_dataLength; i > 0; i--) { this->_bitArray[i] = this->_bitArray[i - 1]; } this->_bitArray[0] = 1; } } } int FirstBigUnrepeatData::GetTheFirstRepeatIndex() //如果输入数字重复,返回输入数字n中相邻位置数字重复的第二个数字的数组表示位置 //如果输入数字不重复,返回0 { for (int i = 0; i < this->_dataLength - 1; i++) { for (int j = i + 1; j < this->_dataLength; j++) { if (this->_bitArray[i] == this->_bitArray[j]) { return j; } } } return -1; } void FirstBigUnrepeatData::Calc() //获得比输入数字n大的不重复数字 { if (_calced == false) { this->_calced = true; while (true) { this->InitBitArray(); int index = this->GetTheFirstRepeatIndex(); if (index <= 0) { break; } this->IncreaseData(index); this->GenerateNewData(); } } } //void main() //{ // GetDiffNum Ln(1989); // int betternum; // betternum = Ln.GetTheNum(); // cout << betternum << endl; //} int _tmain(int argc, _TCHAR* argv[]) { FirstBigUnrepeatData *entity = FirstBigUnrepeatData::Create(1989); cout << entity->GetValue() << endl; FirstBigUnrepeatData *current = entity; for (int i = 0; i < 20; i++) { current = current->Next(); cout << current->GetValue() << endl; } char t; cin >> &t; return 0; }
@519740105:大神我是爱你的啊,没,这个题目有答案的,不过我想自己做,然后写了一堆结果没对,我就想知道自己的代码哪里有问题,大神我知道你能知道的,求解
@邹而语: 你的代码很多都看不懂干吗用的。
我能发现你的错误是:
1、以下代码有问题:
while (temp % 10 != 0)
{
b[i++] = temp % 10;
temp = temp / 10;
}
循环条件应该是
temp != 0
2、以下代码逻辑不正确:
int GetDiffNum::GetThePlace() //如果输入数字重复,返回输入数字n中相邻位置数字重复的第二个数字的数组表示位置 //如果输入数字不重复,返回0
{
if (a[0] == '\0')
return 0;
int i;
for (i = 0; a[i+1] != '\0';i++)
if (a[i] == a[i + 1])
return i + 1;
return 0;
}
不应该这样找出重复的数字(重复的数字不一定相邻)
3、对重复位数字 +1 操作不正确,没考虑到进位的情况,更没有考虑到从n位数变成n+1位数的可能。
4、还是因为你的代码很多看不懂,所以很难指出你的错误在哪里,只能参考你的代码,修改几个地方达成目的。
你可以参考:C++基数排序问题,这里的错误我就好去分析具体的问题。
下面是我小改后的代码:
#include "GetDiffNum.h" GetDiffNum::GetDiffNum(int n) : GetDiffNum() /* 调用初始化函数 */ { temp = n; //输入数字赋值给类的私有变量temp } void GetDiffNum::GetTheArrayDisp() //获得输入数字n的数字表示a[]和有效位数length { int b[10], i, j; i = 0; j = 0; while (temp != 0) /* 此处代码 temp % 10 != 0 修改为 temp != 0 */ { b[i++] = temp % 10; temp = temp / 10; } length = i; //length为数组有效位数 i--; while (i >= 0) a[j++] = b[i--]; //a[j] = '\0'; /* 通过长度 length 来控制结果,不需要用这个数据 */ } void GetDiffNum::GetTheNumDisp() { int i = 0, sum = 0; //while (a[i] != '\0') //{ // sum *= 10; // sum += a[i]; // i++; //} for (i = 0; i < length; i++) /* 使用 length 来控制循环 */ { sum *= 10; sum += a[i]; } temp = sum; } int GetDiffNum::GetThePlace() //如果输入数字重复,返回输入数字n中相邻位置数字重复的第二个数字的数组表示位置 //如果输入数字不重复,返回0 { if (length == 0) { return 0; } /* 判断的是指定位置的数字后面是否有重复的数字,而不是相邻的数字后面是否重复 */ for (int i = 0; i < length - 1; i++) { for (int j = i + 1; j < length; j++) { if (a[i] == a[j]) { return j; } } } /* 以下代码的判断是不正确的 */ //if (a[0] == '\0') // return 0; //int i; //for (i = 0; a[i + 1] != '\0'; i++) // if (a[i] == a[i + 1]) // return i + 1; return 0; } int GetDiffNum::GetTheNum() //获得比输入数字n大的不重复数字 { int k, h, m, i, s, mom; s = 0; mom = 1; GetTheArrayDisp(); k = GetThePlace(); if (k < 0) return -1; //错误,k>=0,基本不考虑 m = k; h = k; if (k == 0) //输入数字不重复 { temp += 1; GetTheArrayDisp(); h = GetThePlace(); if (h == 0) return temp; } /* 以下语句是不正确的,因为要考虑进位 */ //a[h] += 1; /* 此处 +1 要考虑进位 */ /* 修改为以下语句实现重复位 +1 操作 */ int t; while (h >= 0) { t = a[h]; t++; a[h] = t % 10; if (t < 10) { break; } h--; } /* 产生了高位进位 */ if (h < 0 && t > 10) { for (i = length; i > 0; i--) { a[i] = a[i - 1]; } a[0] = 1; length++; } GetTheNumDisp(); GetTheArrayDisp(); h = GetThePlace(); /* 看不懂以下代码干吗的 */ //if (h == 0) // m = k; //else { //while (h <= m&&h != 0) while (h > 0) //修改为这个条件 { // 以下语句不知道干吗的 //m = h; while (h >= 0) { t = a[h]; t++; a[h] = t % 10; if (t < 10) { break; } h--; } /* 产生了高位进位 */ if (h < 0 && t > 10) { for (i = length; i > 0; i--) { a[i] = a[i - 1]; } a[0] = 1; length++; } GetTheNumDisp(); GetTheArrayDisp(); h = GetThePlace(); } } /* 看不懂干吗的。*/ //for (i = m + 1; i < length; i++) //{ // if (a[m] == 0) // { // s += mom; // mom = -mom; // a[i] = s; // } // else // { // a[i] = s; // s += mom; // mom = -mom; // } //} GetTheNumDisp(); return temp; }
@519740105: 不重复数字只要是相邻位置不重复就行了,比如101是不重复,100是重复,0和0重复了,应该是进位和temp!=0的关系,多谢了
@邹而语: 哦。那你这个是另外的一个需求了。可以使用你的那一段代码判断。
@519740105: 嗯,就是那个说看不懂的,看a[h]只要不是0就后面改成0101..要是0,就改成1010..
要看输入方式,如果可以设定输入方式的话,就是将用户的输入当作字符串数字
1.从最右开始循环,第一位+1进位,往后每位不变如果跟前面的重复了.则加1进位,
这个算法还有更快的没?
我错了!