ShiFengshouクイック計算
Shi Fengshouスピードアルゴリズムの革新的な貢献は、高い位置から数え、キャリーを予測することです。従来の手計算を完全に覆す9つのテーブルは必要ありません!
迅速な計算の基本は、1桁を複数桁で乗算することです。
その中で、7を掛けるのが最も複雑です。例として取り上げてください。
1/7は循環小数0.142857 ...であるため、桁数が142857 ...を超える場合は、1を入力する必要
があります。2 / 7、3 / 7、... 6 /についても同様です。7.循環小数。桁数がn / 7を超える場合は、nの
下にプログラムを入力して、ShiFengshou速度アルゴリズムで7を掛ける操作プロセスをシミュレートする必要があります。
7を掛ける1の法則は、偶数を2で掛け、奇数を2で掛け、5を足すというものです。すべてが1だけになります。
7を掛けるキャリールールは次のとおりです。
フル142857 ...から1、
フル285714 ...から2、
フル428571 ...から3、
フル571428 ...から4、
フル714285 ...から5、
フル857142 ... 6にプログラムフローを分析し、下線部分に不足しているコードを入力してください。
// 1桁を計算します
intge_wei(int a)
{ if(a%2 == 0)return(a * 2)%10; else return(a * 2 + 5)%10; }//
计計算決定intjin_wei(char * p)
{ char * level [] = { "142857"、"285714"、"428571"、"571428"、"714285"、"857142" };
char buf [7];
buf [6] = '\ 0';
strncpy(buf、p、6);int i;
for(i = 5; i> = 0; i-){ int r = strcmp(level [i]、buf); if(r <0)return i + 1; while(r == 0){ p + = 6; strncpy(buf、p、6); r = strcmp(level [i]、buf); if(r <0)return i + 1; ______________________________; //ここ空} }
0を返します。
}//複数の桁に7を掛けますvoidf
(char * s)
{ int head = jin_wei(s); if(head> 0)printf( "%d"、head);char * p = s;
while(* p){ int a =(* p-'0 '); int x =(ge_wei(a)+ jin_wei(p + 1))%10; printf( "%d"、x); p ++; }printf( "\ n");
}int main()
{ f( "428571428571"); f( "34553834937543"); 0を返します。}
問題分析
アイデア:
高次演算の場合、アイデアは次のようになります。最初の6ビット文字がbufに格納され、最大レベルと比較されるたびに、最大レベルよりも大きい場合、キャリーは6であり、残りも順番に比較されます。
bufをレベル[i]と比較します。bufがレベル[i]より大きい場合、現在のbufがレベル[i]より大きいことを意味するため、キャリーが必要であり、キャリー桁はi + 1です(ここでのロジックキャリー関数のコードから取得できます)。buf = level [i]の場合、現在のbuf文字列がlevelの文字列と等しいことを意味します。後で比較する必要があります。つまり、元の文字列の最後の6桁を取得して、bufに格納します。レベルキャリーと比較します。このように比較し続けます。問題は、常にbufがlevel [i]よりも大きい前に、i + 1(質問の意味コードで指定)を返し、bufがレベルよりも小さい場合です。 [i]、そうですか?定数値を返しますか?これは記入する部分です。考えてみれば、bufは現在のレベル[i]より大きく、前のレベルが返されるので、i + 1が返されます。その後、bufは現在のレベルより小さく、戻り値は現在のレベルのiです。 (類推による)この推測を試して、空白の塗りつぶしのコードと前のコードの連続性を考慮してください。前のr <0の場合、後ろのr> 0の状況を考慮する必要があります。最後に、推測を試して、電卓で確認します。
具体的なコード分析は次のとおりです。
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
//计算个位?
int ge_wei(int a)
{
if(a % 2 == 0)
return (a * 2) % 10;
else
return (a * 2 + 5) % 10;
}
//计算进位?
int jin_wei(char* p)
{
char* level[] = {
"142857",
"285714",
"428571",
"571428",
"714285",
"857142"
};
char buf[7];
buf[6] = '\0';
strncpy(buf, p, 6);
int i;
for(i=5; i>=0; i--){
int r = strcmp(level[i], buf);
if(r < 0) return i+1; //level[i] < buf,得出进位数i+1
while(r==0){ //level[i] = buf
p += 6; //往后偏移6位,看看剩下的6位再比较,就是前面的一样,那么往后比较
strncpy(buf,p,6);
r = strcmp(level[i], buf);
if(r < 0) //buf 更大 ,进位为前一个i,即i+1
return i+1;
// ______________________________; ?//填空
if(r > 0) //buf 更小 ,进位为当前为i
return i;
}
}
return 0;
}
//多位数乘以7
void f(char* s)
{
int head = jin_wei(s); //head是s的进位
if(head > 0) printf("%d", head); //输出进位
char* p = s;
while(*p){
int a = (*p - '0'); //字符转数字
int x = (ge_wei(a) + jin_wei(p+1)) % 10; //个位+后者字符串的进位取个位
printf("%d",x);
p++;
}
printf("\n");
}
int main()
{
f("428571428571");
f("34553834937543");
return 0;
}