Data_Structure/作業/unit2/DS2/DS2.c
2025-01-20 21:25:33 +08:00

322 lines
7.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define MAX 10
// 儲存每一項的結構
struct Term {
int coefficient; // 係數
int exponent; // 指數
};
//計算可能的解
void count_root(int arrR[],int arrL[],int ans[],int countF,int countL ,int *len_ans){
int i , j ,k=0;
for(i=0;i<countF;i++){
for(j=0;j<countL;j++){
if((arrL[j]%arrR[i])==0){
ans[k++] = arrL[j]/arrR[i];
}
}
}*len_ans =k;
}
//將最高次係數與常數的因數加入負號
void plus_root_negative(int arr[],int *len){
int i , j=0;
for(i=0;i<*len;i++){
arr[*len+j]=-(arr[i]);
j++;
}*len=*len+j;
}
//找最高次係數與常數的因數
void find_factor(int P[], int facF[], int facL[], int len, int *count1, int *count2) {
int i, j = 0;
for (i = 1; i <= abs(ceil(P[2] / 2)); i++) {
if (abs(P[2]) % i == 0) {
facF[j++] = i;
}
}
facF[j++] = fabs(P[2]); // 包含 P[2] 本身
*count1 = j; // 設定找到的因數個數
j = 0;
for (i = 1 ; i <= abs(ceil(P[len-1] / 2)); i++) {
if (abs(P[len-1]) % i == 0) {
facL[j++] = i;
}
}
facL[j++] = fabs(P[len-1]); // 包含 P[len] 本身
*count2 = j; // 設定找到的因數個數
}
//把根代入方程式
int evaluate_polynomial(int A[], int len, int x) {
int result = 0;
int i;
for (i = 2; i < len; i += 2) {
result += A[i] * pow(x, A[i-1]);
}
return result;
}
//把根代入方程式 求答案
void Substitute(int len_root, int arr[], int ans[], int A[], int len_A, int *len_ans) {
int i, j = 0, result;
for (i = 0; i < len_root; i++) {
result = evaluate_polynomial(A, len_A, arr[i]);
// printf("x = %d, result = %d\n", arr[i], result);
if (result == 0) {
ans[j++] = arr[i];
}
}
*len_ans = j;
}
//移除重複的答案
void remove_duplicates(int A[], int len, int new_A[], int *new_len) {
int i, j, k;
int is_duplicate;
*new_len = 0; // 初始化新的陣列長度為0
// 遍歷原始陣列
for (i = 0; i < len; i++) {
is_duplicate = 0; // 假設當前元素沒有重複
// 檢查是否在結果陣列中出現過
for (j = 0; j < *new_len; j++) {
if (A[i] == new_A[j]) {
is_duplicate = 1; // 如果發現重複標記為1
break;
}
}
// 如果沒有重複,將其加入結果陣列
if (!is_duplicate) {
new_A[*new_len] = A[i];
(*new_len)++; // 更新結果陣列的長度
}
}
}
//顯示方程式
void output(int *A,int len){
int i ,j,flag_Max=0,flag_x=0, flag_const=0 ;
printf("\n方程式p(x)= ");
//A[i]為指數 A[i+1]為係數
//i從1開始數 一次讀取一個指數與係數
//len為A[]的長度
//flag_Max 為最高次項的旗標
//flag_x 為1次項的旗標
//flag_const 為常數項的旗標
for(i=1;i<len;i++){
if(A[i]==1){ //若指數項=1 觸發一次項旗標
flag_x=1;
}else if(A[i]==0){ //若指數項=0 觸發常數項旗標
flag_const=1;
}
if(flag_Max==0){ //第一項
if( A[i]>1 && A[i+1]!=1){ //指數大於1 係數不等於1
printf("%dx^%d",A[i+1],A[i]);
}else if(A[i]>1 && A[i+1]==1){
printf("x^%d",A[i]); //指數大於1 係數等於1
}else if(A[i]==1 && A[i+1]!=1){ //指數=1 係數不等於1
printf("%dx",A[i+1]);
}else if(A[i]==0 && A[i+1]!=1){ //指數=0 係數不等於1
printf("%d",A[i+1]);
}else if(A[i]==1 && A[i+1]==1){ //指數=1 係數=1
printf("x");
}else if(A[i]==1 && A[i+1]==-1){ //指數=1 係數=-1
printf("-x");
}flag_Max = 1; //高次項的旗標=1
}else if(flag_x == 1 && flag_const==0){// x一次項
if(A[i+1]>0){ // x一次項為正
if(A[i+1]==1){
printf("+x",A[i+1]);
}else{
printf("+%dx",A[i+1]);
}
}else if(A[i+1]<0){ //x一次項為負
if(A[i+1]==-1){
printf("-x",A[i+1]);
}else{
printf("%dx",A[i+1]);
}
}
}else if(flag_const==1){ // 常數項
if(A[i+1]>0){ //常數項>0
printf("+%d",A[i+1]);
}else if(A[i+1]<0) { //常數項<0
printf("%d",A[i+1]);
}
}else if(flag_Max==1 && flag_x==0 && flag_const==0) { //多項式中間的部分
if(A[i+1]>0){ //係數>1
if(A[i+1]==1){ //係數=1
printf("x^%d",A[i]);
}else{ //係數不等於1
printf("+%dx^%d",A[i+1],A[i]);
}
}else if(A[i+1]<0){ //係數<1
if(A[i+1]==-1){ //係數=-1
printf("-x^%d",A[i]);
}else{ //係數不等於1
printf("%dx^%d",A[i+1],A[i]);
}
}
}i++;
}
printf("\n");
}
int main() {
int i,j, len, countF, countL, len_root, len_ans ,len_new ;
char input[100];
struct Term terms[MAX];
int term_count = 0;
printf("\n*** 解多項式之整數根 ***\n");
// 1. 讀取輸入
printf("\n請輸入多項式: ");
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\n")] = 0; // 移除換行符
// 2. 處理每一項
char *ptr = input;
while (*ptr && term_count < MAX) {
int coef = 0, exp = 0;
int is_negative = 0;
// 檢查負號
if (*ptr == '-') {
is_negative = 1;
ptr++;
} else if (*ptr == '+') {
ptr++;
}
// 跳過空白字符
while (isspace(*ptr)) ptr++;
// 3. 解析每一項
if (sscanf(ptr, "%dx^%d", &coef, &exp) == 2) {
// 完整的 ax^b 形式
ptr = strchr(ptr, '^') + 1;
} else if (sscanf(ptr, "%dx", &coef) == 1) {
// ax 形式指數為1
exp = 1;
ptr = strchr(ptr, 'x') + 1;
} else if (sscanf(ptr, "x^%d", &exp) == 1) {
// x^b 形式係數為1
coef = 1;
ptr = strchr(ptr, '^') + 1;
} else if (strncmp(ptr, "x", 1) == 0) {
// 單獨的 x係數為1指數為1
coef = 1;
exp = 1;
ptr++;
} else {
// 假設是常數項
sscanf(ptr, "%d", &coef);
exp = 0;
while (isdigit(*ptr)) ptr++;
}
// 4. 處理負號
if (is_negative) {
coef = -coef;
}
// 5. 儲存結果
terms[term_count].coefficient = coef;
terms[term_count].exponent = exp;
term_count++;
// 輸出當前項的信息(用於調試)
// printf("項 %d: 係數 = %d, 指數 = %d\n", term_count, coef, exp);
// 移動到下一個 '+' 或 '-' 符號
while (*ptr && *ptr != '+' && *ptr != '-') ptr++;
}
// int *A = (int*)malloc(((term_count*2)+1) * sizeof(int)) ;
len = ((term_count*2)+1);
int A[len];
// printf("term_count=%d\n",term_count);
// printf("((term_count*2)+1)=%d\n",((term_count*2)+1));
// printf("sizeof(A)=%d\n",sizeof(A));
A[0]=term_count;
for (i = 1 , j=0 ; i < term_count*2 ; i++ , j++ ){
A[i]= terms[j].exponent;
A[i+1]= terms[j].coefficient;
// printf("A[%d]=%d\n",i,terms[j].exponent);
// printf("A[%d]=%d\n",i+1,terms[j].coefficient);
i++;
}
// printf("A[]= ");
// for (i = 0; i < len; i++) {
// printf(" %d ",A[i]);
// }
// printf("\n");
// 1x^3-2x^2-1x^1+2x^0
// 1x^5-1x^3-1x^2-1x^1+1x^0
// 1x^2-100x^0
// 1x^2+100x^0
// 3x^4+9x^3-198x^2+156x^1+360x^0
int facF[30], facL[30], root[60], ans[60] ,new_ans[8];
find_factor(A, facF, facL, len, &countF, &countL);
// printf("最高次方項因數為: ");
// for (i = 0; i < countF; i++) {
// printf("%d ", facF[i]);
// }
// printf("\n常數項因數為: ");
// for (i = 0; i < countL; i++) {
// printf("%d ", facL[i]);
// }
// printf("\n");
count_root(facF, facL, root, countF, countL, &len_root);
plus_root_negative(root, &len_root);
// printf("可能的根:\n");
// for (i = 0; i < len_root; i++) {
// printf("root[%d] = %d\n", i, root[i]);
// }
//輸出多項式
output(A,len);
// 計算可能的解
Substitute(len_root, root, ans, A, len, &len_ans);
//移除多餘的解
remove_duplicates(ans,len_ans,new_ans,&len_new);
if(len_new==0){
printf("\n整數根不存在");
return 1 ;
}
if(len_new>0){
printf("\n解得整數根為:");
for (i = 0; i < len_new; i++) {
if(i<len_new-1) {
printf("%d、",new_ans[i]);
}else if(i==len_new-1) {
printf("%d", new_ans[i]);
}
}
}
return 0;
}