真正的不重复数字实现,像人一样去编程
題目要求如下:
如果一個數字十進制表達時,不存在連續兩位相同,則稱之為“不重復數”。例如,105、164和198都是“不重復數”,而11、100和122不是。實現一個函數,用一個long類型( long類型數字A),實現返回大于A的最小“不重復數”。
看到兩個朋友在做這個算法題
趣味算法:返回不重復數的實現? 夏小冰
算法,一個永恒的話題,挑戰你的編程之美?winzheng
夏小冰的代碼,運算時1122, 18, 21,123, 98都有正確結果,但是100011,121989999的答案是錯的
winzheng的結果如下
A=1122, 18, 21,123, 98,100011,121989999
結果:1201,19,23,124,101,101010,123010101
看起來功能都是實現了
但是仔細看代碼他是把輸入的A不斷加1,并且判斷結果的數字是否符合要求?
//只要是一個人,就不會這么去做的(sorry,兄弟)
*其實我們在編程的時候更多的要從自身角度出發。從問題的固有規律出發,設想一個人是如何來解決這個問題的。并且把解決問題的步驟轉化為程序,就能寫出比較好的算法了。
想想如果給一個人一個100位長的數字,他會用這種不斷加1的辦法來解決問題嗎?
《編程之美》
這個是winzheng的標題,不過從他的代碼里只能感受到對CPU無情的蹂躪。
以至于
如果數據更大,例如:121989999991999,花了好幾分鐘也沒算出來,這個時候真的需要考慮時間復雜度等問題了。
解決這個問題只要把計算機當人看就可以了
1、將輸入數加1
2、人類會從最高位的下一位作為當前位開始逐位尋找相鄰的連續數,如果沒有,則該數字就是目標值
3、如果當前位和前一位相同,把當前位的數字加1
3.1 如果加1后導致進位,則當前位等于前一位,前一位加1,返回3.1
3.2 加1后不進位,返回原始數字最高位到當前位的數據,后續拼接上“0101…”組成的剩余部分即可
3.3 進位到最高位,則返回1,后續拼接上“0101…”組成的剩余部分即可
代碼如下
?
public static long GetNextNotDuplicatedValue4(long a)
??????? {
??????????? //原始數據轉換成數組
??????????? char[] arr = a.ToString().ToCharArray();
??????????? //從最高位的下一位作為當前位開始逐位尋找相鄰的連續數
??????????? for (int i = 1; i < arr.Length; i++)
??????????? {
??????????????? //如果相鄰兩位重復
??????????????? if (arr[i - 1] == arr[i])
??????????????? {
??????????????????? //如果當前位和前一位相同
??????????????????? while (i > 0 && arr[i - 1] == arr[i])
??????????????????? {
??????????????????????? //把當前位的數字加1
??????????????????????? arr[i] = (char)((arr[i] - 48 + 1) % 10 + 48);
??????????????????????? //如果加1后導致進位
??????????????????????? while (i > 0 && arr[i] == '0')
??????????????????????? {
??????????????????????????? //前一位加1
??????????????????????????? arr[i - 1] = (char)((arr[i - 1] - 48 + 1) % 10+48);
??????????????????????????? //當前位等于前一位
??????????????????????????? i--;
??????????????????????? }
??????????????????? }
??????????????????? //加1后不進位(i != 0),返回原始數字最高位到當前位的數據,后續拼接上“0101…”組成的剩余部分即可
??????????????????? //進位到最高位(i == 0),則返回1,后續拼接上“0101…”組成的剩余部分即可
??????????????????? string t = i == 0 ? "1" : new string(arr.TakeWhile((item, index) => index <= i).ToArray());
??????????????????? return long.Parse(t + makestring2(arr.Length - i-Math.Sign(i)*1));
??????????????? }
??????????? }
??????????? //如果沒有,則該數字就是目標值
??????????? return a;
??????? }
static string makestring2(int i)
??????? {
??????????? StringBuilder s = new StringBuilder(i);
??????????? for (int j = 0; j < i; j++)
??????????? {
??????????????? s.Append(j % 2==0? "0" : "1");
??????????? }
??????????? return s.ToString(); ;
??????? }
?
運行速度僅和A的位數部分相關
計算121989999991999也是瞬間的
總結:
把計算機當親兄弟來看待,雖然他傻得只會不知疲倦得做加法
另外:
算法絕不是書上學來的那幾種
環顧一下四周,想想人類是如何改變世界的,然后再讓計算機兄弟來幫忙
測試數據也是非常重要的一個東西
轉載于:https://www.cnblogs.com/Chinese-xu/archive/2009/09/05/1560905.html
總結
以上是生活随笔為你收集整理的真正的不重复数字实现,像人一样去编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET用户登录模块代码
- 下一篇: fckeditor编辑器上传文件出现in