Схема горнера в переводе больших чисел из одной системы счисления в другую - C (СИ)
Формулировка задачи:
Здравствуйте! Очень нужна ваша помощь в написании программы. Есть псевдокод, нужно реализовать на си...
http://www.hse.ru/pubs/lib/data/acce...1%81%D1%82.pdf
Решение задачи: «Схема горнера в переводе больших чисел из одной системы счисления в другую»
textual
Листинг программы
#include<stdio.h>
#include<locale.h>
#include<conio.h>
#include<malloc.h>
int fcount(int n, int h)
{ if(n==0) return 0;
int q=n;
int i=0;
int r;
while(q)
{
r=n%h;
q=(n-r)/h;
n=q;
i++;
}
return (i-1);
}
int inverse_vect(int *arr, int count)
{
int *F = (int*)malloc(count*sizeof(int));
for(int i=0;i<=count;i++)
F[i]=arr[i];
for(int i=0;i<=count;i++)
arr[count-i]=F[i];
return *arr;
}
int mul_pol(int *P, int *Q,int *mul,int lP, int lQ)
{
int mp=lP, mq=lQ;
int mPQ=mp+mq;
int i,j;
for(i=0;i<=mPQ;i++) mul[i]=0;
for(i=0;i<mp;i++)
for(j=0;j<mq;j++) mul[i+j]+=P[i]*Q[j];
return *mul;
}
int mul_pol_num_h(int *P, int *Q, int h,int lP, int lQ)
{
int count=lP+lQ;
int *C = (int*)malloc(count*sizeof(int));
mul_pol(P,Q,C,lP,lQ);
inverse_vect(C,count);
int k=0;
Q[k]=C[k]%h;
int q=(C[k]-Q[k])/h;
while(k<=count)
{k++;Q[k]=(C[k]+q)%h; q=(C[k]+q-Q[k])/h;}
k=count+1;
while(q>0)
{Q[k]=q%h; q=(q-Q[k])/h;k=k+1;}
count=k-1;
inverse_vect(Q,count);
printf("\nUG:");
for(int i=0;i<=count;i++) printf("(%d)",Q[i]);
return *Q;
}
int sum_pol(int *R,int *P,int *Q,int lP, int lQ)
{
int mPQ=lP-lQ;
int mQP=lQ-lP;
printf("\n%d-------%d\n",mPQ,mQP);
for(int i=0;i<=lP;i++) if(mPQ==0) {R[i]=P[i]+Q[i]; printf("R%dP%dQ%d\n", R[i],P[i],Q[i]);}
for(int i=0;i<=lP;i++)
{
if(mPQ>0&&i<mPQ) R[i]=P[i];
if(mPQ>0&&i>=mPQ) R[i]=P[i]+Q[i-mPQ];
}
for(int i=0;i<=lQ;i++)
{
if(mQP>0&&i<mQP) R[i]=Q[i];
if(mQP>0&&i>=mQP) R[i]=P[i-mQP]+Q[i];
}
printf("\n");
for(int i=0;i<=lP;i++) printf("!!%d>", R[i]);
return *R;
}
int sum_pol_num_h(int *P,int *Q,int h,int lP, int lQ,int k)
{
int *R = (int*)malloc((lP+lQ)*sizeof(int));
sum_pol(R,P,Q,lP,lQ);
inverse_vect(R,lP);
int t=0,r;
for(int i=0;i<=lP;i++)
{
R[i]=R[i]+t; Q[i]=R[i]; r=Q[i]%h;Q[i]=r;t=(R[i]-r)/h;
}
while(t)
{
r=t%h;Q[lP+k]=r;t=(t-r)/h;k++;
}
inverse_vect(Q,lP);
return *Q;
}
int h_based_rep(int *arr, int n, int h,int count)
{
int r;
/*if(n==0){arr[0]=0; return *arr;}*/
int q=n;
int i=0;
while(q)
{
r=n%h;
q=(n-r)/h;
arr[i]=r;
n=q;
i++;
}
return inverse_vect(arr,count);
}
int hg_based_pol_num(int *a, int h, int g, int z)
{
int i,k,count;
if(h==g) return *a;
count=fcount(h,g);
int last_hg=count;
//count==0?????;
int *hg = (int*)malloc(count*sizeof(int));
h_based_rep(hg,h,g,count);
printf("\nHG");
for(int i=0;i<=count;i++)
printf("!%d", hg[i]);
printf("\n");
count=fcount(a[0],g);
int last_ug=count;
int *ug = (int*)malloc((count)*sizeof(int));
h_based_rep(ug,a[0],g,count);
printf("\nUG");
for(int i=0;i<=count;i++)
printf("!%d", ug[i]);
printf("\n");
/*count=last_hg+last_ug;
int *C = (int*)malloc(count*sizeof(int));*/
/*mul_pol(hg,ug,C,last_hg,last_ug);*/
for(k=1;k<z;k++)
{
mul_pol_num_h(hg,ug,g,last_hg,last_ug);
/*printf("\nUG%d ",k);
for(i=0;i<=count;i++) printf("%d|", ug[i]);*/
int count2=fcount(a[k],g);
/*printf("\n<%d><%d>",a[k],count2);*/
int *ag = (int*)malloc(count2*sizeof(int));
h_based_rep(ag,a[k],g,count2);
printf("\nAG%d: ",k);
for(i=0;i<=count2;i++) printf("%d| ", ag[i]);
sum_pol_num_h(ag,ug,g,last_hg,last_ug,k);
}
printf("\n");
for(int i=0;i<=count;i++) printf("(%d) ", ug[i]);
return *ug;
}
int main(void)
{
int h,g,z;
setlocale(LC_ALL, "russian");
printf("Перевод больших чисел из одной системы счисления в другую по схеме горнера\n");
printf("Введите h и g");
scanf("%d %d", &h, &g);
printf("Введите степень полинома");
scanf("%d", &z);
int *a = (int*)malloc(z*sizeof(int));
printf("Заполните массив");
for(int i=0;i<z;i++)
scanf("%d", &a[i]);
hg_based_pol_num(a,h,g,z);
getch();
return 0;
}
Объяснение кода листинга программы
Код выполняет перевод больших чисел из одной системы счисления в другую по схеме Горнера. Список функций:
- fcount - функция для подсчета количества цифр в числе
- inverse_vect - функция для инвертирования вектора
- mul_pol - функция для умножения полинома на число
- mul_pol_num_h - функция для умножения полинома на число с учетом разложения на множители
- sum_pol - функция для сложения полинома и числа
- sum_pol_num_h - функция для сложения полинома и числа с учетом разложения на множители
- h_based_rep - функция для представления числа в системе счисления с основанием h
- hg_based_pol_num - функция для перевода полинома из одной системы счисления в другую Список переменных:
- h - основание системы счисления
- g - степень полинома
- z - количество чисел для перевода
- a - массив для хранения чисел
- r - остаток от деления числа на g
- q - частное от деления числа на g
- t - временная переменная для хранения остатка от деления числа на h
- k - счетчик для отображения разложения числа на множители
- mPQ - количество цифр в числе P
- mQP - количество цифр в числе Q
- R - массив для хранения суммы полинома и числа
- P - массив для хранения полинома
- Q - массив для хранения числа
- C - массив для хранения разложения числа на множители
- ug - массив для хранения числа после перевода полинома из одной системы счисления в другую
- ag - массив для хранения числа после разложения числа на множители Пример использования: Введите h и g, например, 10 и 20. Введите степень полинома, например, 3. Введите числа для перевода, например, 123456789. Программа выведет результат перевода числа в систему счисления с основанием 10 и степенью полинома 3: UG: 123|456|789 R: 123 456 789