我試圖有效地列出1和100之間的數字。但是我必須擺脫具有相同數字的數字。
實施例: 12根據該規則是相同的21 13是31 14是41 所以for循環也不會越過相同的數字。
我在想一些技巧,比如從1到100的所有數字,然後刪除找到的當前編號的排列。 我問這個的原因是因爲像100000這樣的大限制會失敗。 又如: 124等於142,241,214,412,421C++中的唯一編號
回答
您可以申請遞歸。這個函數的原型是那麼喜歡:
print_digits(int num_of_remaining_digits,int start_from_digit, int current_number);
編輯:完成我在這裏我的解決方案(我認爲這不是從本福格特和升輸出順序
void print_digits(int num_of_remaining_digits,int start_from_digit, int current_number)
{
if(num_of_remaining_digits == 0)
{
std::cout << current_number << std::endl;
return;
}
for(int i=start_from_digit;i<=9;i++)
{
print_digits(num_of_remaining_digits-1,i,10*current_number+i);
}
}
更好readbility這裏是測試代碼
這是如何工作的?
它是遞歸中的經典之一。首先有停止條件。然後是主循環。
主循環從start_from_digit
開始,因爲所有生成的數字都將以非遞減順序排列。舉例來說,如果current_number
是15
它會調用print_digits
蒙山
print_digits(num_of_remaining_digits-1,5,155)
print_digits(num_of_remaining_digits-1,6,156)
print_digits(num_of_remaining_digits-1,7,157)
print_digits(num_of_remaining_digits-1,8,158)
print_digits(num_of_remaining_digits-1,9,159)
在每一個調用它會檢查,如果我們達到最終白衣num_of_remaining_digits
,如果不繼續使用該被推爲start_from_digit
(第二PARAM)位數current_number
好像它可以這樣簡單:
list = {}
for (j = 1 to 100)
if (j is not excluded from list)
list += j;
真的,只有if
條件有趣的是:需要檢查列表的所有相關屬性項目。
我會通過超載正確的操作員(從我的頭頂應該只是less
)和std::set
來寫一個適合您比較需求的課程。
創建一個函數,該函數接受一個字符串,並返回一個字符串數組,其中包含該字符串中字符的所有可能排列組合。這並不難,但它可能是最簡單的遞歸。雖然說起來容易做起來難。
一旦你有了這個函數,並且它返回數組,你只需要遍歷數組並刪除與數組中的一個共享數的indecies。
您正在尋找某些字符(0..9)與特定長度(100 = 2,1000 = 3)的組合。
看看這裏Algorithm to return all combinations of k elements from n
謝謝法比奧,看起來像是可以幫助我的東西 – Ali 2012-01-29 21:03:36
這絕對是要走的路。 – user450018 2012-01-29 21:07:06
我會用一個散列表,像這樣
1)從派生的數字中派生出一個密鑰,使得具有相同數字的數字具有相同的密鑰(例如總和數字,所以「124」和「142」有關鍵7,或拿(+1)的乘積,因此「124」和「142」具有密鑰30-必須對數字+1 +1)
2)將數字放入由密鑰
索引的散列表中現在,關於您是否已經擁有數字相同的數字的測試僅限於散列表中具有相同鍵的實體。這種算法需要線性存儲,其性能取決於您可以提供多少密鑰。
首先,觀察你的規則與第一個數字= 1
生成所有2位數字不包括11(爲什麼?)
開始倍數現在,生成所有2位數第一個數字= 2,但不生成任何與第一個列表中的數字匹配的數字。
重複3,但不要從前兩個列表中生成任何數字。
請注意,對於任何2位數的數字ab,如果符合條件,則必須是< b,否則您已經生成了相應的數字ba。
在PASCAL語言中,只是因爲我覺得一文不值:
var i:integer; j:integer;
begin
for i := 1 to 8 do
for j := i+1 to 9 do
println(i*10+j);
end;
增加了稍晚
注意要生成的數字總是有自己的數字嚴格單調遞增。對於數字2abc資格,觀察2 < a < b < c。 (實施例:2539是一個匹配2359,並應被拒絕。)
相同的數字a Ali 2012-01-29 21:10:01
我會使用一個set
爲的號碼的數字的置換:
std::vector<int> list_unwanted = digit_permutations(number);
std::unordered_set<int> set_unwanted(begin(list_unwanted), end(list_unwanted));
然後循環從0到極限,通過檢查增加不必要的數字,如果他們在集合set_unwanted
:
std::vector<int> numbers;
numbers.reserve(limit - set_unwanted.count());
for (int i = 0; i < limit; ++i)
if (!set_unwanted.count(i))
如果你有一組數字,這組的任何排列是不是一個有效的解決方案,所以首先進行功能如果一組數字是另一組的排列,則確定R集。 要獲得單個數字,您可以遞歸地除以10,直到獲得零值。 如果你把所有的數字像[1,2,4]數組,以檢查是否antoher陣列是antoher集的置換(你選擇了它,只有當他們具有相同的長度):
bool permutation(int *a, int *b, int n) // n leading dimension
{
bool result=true, vector[n]={false};
for(int i=0;i<n;i++)
{
for(int j=0;j<n ;j++)
{
if(a[i]==b[j])
vector[i]=false;
}
}
for(int i=0;i<n && result;i++)
result=(vector[i]==true); // if vector[i] is false, result is false, is
// not a permutation and the loop ends
return result;
}
我沒有測試過,但我認爲它有效,否則告訴我。 至於把所有的數字放在一個數組中,我認爲這很容易。 一旦生成所有數字,您檢查確定的數字不是一個已經採取的數字的排列。
如果我不明白錯誤,它適用,就好像一個數字是預填的數字的排列組合。謝謝你的貢獻,但我更喜歡不**不尋找未來的數字。如果發現號碼124發現循環**不應該再次超過241,214。 – Ali 2012-01-29 21:17:42
我意識到這是錯誤的,如果我有一個數組[1,1,1]和[1,2,3],這個函數返回true。 – 2012-01-29 21:23:39
#include <stdio.h>
size_t enum_canonical(char* begin, char* end, char min, char max)
{
if (begin == end) {
puts(begin);
putchar('\n');
return 1;
}
size_t result_count = 0;
--end;
for(*end = min; *end <= max; ++*end)
result_count += enum_canonical(begin, end, min, *end);
return result_count;
}
int main(void)
{
char buff[7];
printf("%d results\n", enum_canonical(buff, &(buff[6] = '\0'), '0', '9'));
}
非常感謝您的幫助。 – Ali 2012-01-29 21:23:02
@rolandbishop:請注意,這與[ralu]提到的方法(http://stackoverflow.com/a/9056758/103167)完全相同。 – 2012-01-29 21:23:58
+1,但仍然這個代碼將運行得像你的一樣快http://ideone.com/RTXqQ :) – 2012-01-29 23:06:47
這是我的想法,每個值把它的數字在一組。使用該設置作爲另一組的密鑰,以跟蹤哪些數字已被使用。在我的情況下,我使用位字段作爲數字的集合,即數字0用1表示,數字1用2表示(2等於4等等)。太累了解釋,這裏的塔codez:
unsigned int get_digits(int v)
{
unsigned int rv = 0;
do
{
rv |= 1 << (v % 10);
v /= 10;
} while(v);
return rv;
}
void unique_ints(int n)
{
std::set<unsigned int> used_combinations;
for(int i = 0; i < n; ++i)
{
const unsigned int d = get_digits(i);
if(used_combinations.find(d) == used_combinations.end())
{
used_combinations.insert(d);
// cout or some other way to store the value
std::cout << i << std::endl;
}
}
}
讓我們1到1000由於有4位在1000,我打印1爲0001,所以0001,0010,0100,1000是相同數量按我算法。 0120,0012,0210,0102,0201,0021也是相同的數字。
下面是程序:
int main()
{
int i=0, j=0, k=0;
while(i<=9)
{
int unique=(i*100 + j*10 + k);
printf("unique number : %3d\n", unique);
if(j==9 && k==9)
{
i++;
k=i;
j=i;
}
else if(k==9)
{
j++;
k=j;
}
else
k++;
}
}
- 1. C++ reinterpret_cast,使唯一編號
- 2. 生成唯一編號
- 3. SQL和PHP唯一編號
- 4. 唯一編號列表
- 5. 打印唯一編號
- 6. 如何在C#或SQL Server中生成6位唯一編號?
- 7. 唯一訪客按鈕在vb.net上的唯一編號?
- 8. 二叉樹的唯一編號節點
- 9. 獲得新的唯一編號
- 10. node.js,mongo快速保存唯一編號
- 11. Crossfilter和DC.js:縮小到唯一編號
- 12. 唯一8位增量編號
- 13. 在Wordpress帖子中添加一個唯一的帖子編號
- 14. 需要生成與BDD的蟒蛇中的唯一編號
- 15. 將列值除以R中的多個列的唯一編號
- 16. 提供一系列唯一編號(C#vs Sql)的好方法是什麼?
- 17. 從陣列中獲取最高但也是唯一的編號
- 18. 在陣列中找到的最小唯一編號
- 19. 根據Javascript中的字符串輸入生成唯一編號
- 20. Access數據庫中的唯一成員編號
- 21. 如何使用遞歸方法在C#中創建隨機唯一編號?
- 22. 獲取範圍中的唯一號碼
- 23. 將名稱字符串編碼爲唯一編號
- 24. 在java應用程序中生成12位唯一編號
- 25. 在數據庫中生成自動唯一編號
- 26. python從日期範圍中找到唯一日期編號爲
- 27. 在Excel中添加唯一編號以複製單元格
- 28. 如何在紅移中生成12位唯一編號?
- 29. 確保基於SEQ編號的記錄應該是唯一的?
- 30. PHP的編號通過唯一的ID分組
你爲什麼要得到相同的數字擺脫數字的?這是一個家庭作業問題嗎? – 2012-01-29 20:52:14
這裏有問題嗎? – talonmies 2012-01-29 20:53:09
看起來像一個家庭作業。你有什麼問題編寫代碼? – bratao 2012-01-29 20:54:49