從鍵盤輸入分子b和分母a,判斷該分數(真分數)是否是無限循環小數,並給出循環開始出現的位數。驗證如下結論是否正確:
(對於分數b/a,小數點至多a位, 或a位之內開始出現無限循環。)
例如:
3/8 = 0.375 //小數點不超過7位(有限小數)
1/3 = 0.333333...//從1位開始出現無限循環
1/7 = 0.142857 142857 142857 //6位開始(7位內)出現循環序列:142857
6/7 = 0.857142 857142 857142 //6位開始(7位內)出現循環序列:857142
(試試神奇的分數1/49和100/9801,100/9899)
提示:
假設分數是3/8=0.375
小數第1位上的數字是30/8的商,就是表達式30/8的值:3
30%8(求余)的值是6,那么 小數第2位上的數字是60/8的值:7
60%8(求余)的值是4,那么,小數第3位上的數字是40/8的值:5
再寫的過程中遇到很多問題,逐一解決,所以在代碼中可能有些復雜不夠精簡,限於作者水平。。。。。
此題必然還有更為簡便的方案,下次想出來再改;
首先利用題目所給方法求出其小數部分,然后我的想法是取出 2a 個小數點后的數字逐一判斷;
但是呢,問題出現在數字重復可能不是循環的,因為他可能就連續出現幾個一樣的數字;
這個問題困擾了很久,最后解決的方案不太理想,但也能解決;
其他的循環與不循環相對較容易;
代碼如下:
1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 int b,a; 7 cin>>b>>a; 8 int arr[a*2+1] ,i,j,k,temp,m,n; 9 int sign,sum = 0; 10 temp = b; 11 for(i = 1; i <= a*2; i++) // 2a位小數 12 { 13 temp *= 10; 14 arr[i] = temp / a; 15 temp %= a; 16 // cout<<arr[i]; 17 if(i>a) 18 sum += arr[i]; 19 } 20 if(sum == 0) 21 cout<<"該分數為有限小數"<<endl; 22 else 23 { 24 for(i = 1;i <= 2*a;i++) 25 { 26 for(j = 1;j < i;j++) // 有相等 27 { 28 if(arr[i] == arr[j]) 29 { 30 sign = 0; 31 m = i-j; // 循環位數 32 if(m != 1) // 必為不相同循環 2 329 33 { 34 for(k = 1;k < a;k++) // 保證中間無小段循環 35 if(arr[i+k] != arr[j+k]) 36 sign++; 37 } 38 else // 必為相同循環 39 { 40 for(k = 1;k <= a - j;k++) 41 if(arr[j] != arr[j+k]) 42 sign++; 43 } 44 } 45 if(sign == 0) // 確定為循環 46 { 47 n = i - 1; // 起始循環點 48 break; 49 } 50 } 51 if(sign == 0) 52 break; 53 } 54 if(sign == 0) 55 cout<<"該分數為無限循環小數,循環位數:"<<n<<endl; 56 else 57 cout<<"該分數為無限不循環小數"<<endl; 58 } 59 return 0; 60 }
測試例子:
3 8
1 3
1 7
1 49
輸出:
該分數為有限小數
該分數為無限循環小數,循環位數:1
該分數為無限循環小數,循環位數:6
該分數為無限循環小數,循環位數:42
2020-01-1115:35:53