265 lines
5.6 KiB
C++
265 lines
5.6 KiB
C++
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <math.h>
|
||
#include <string.h>
|
||
#include <ctype.h>
|
||
|
||
typedef struct node {
|
||
int coef;
|
||
int exp;
|
||
int root;
|
||
struct node* rlink;
|
||
struct node* llink;
|
||
} node;
|
||
node *head, *tail, *current, *prev, *temp ,*head_root , *current_root , *tail_root;
|
||
|
||
void init_f() {
|
||
head = (node *)malloc(sizeof(node));
|
||
tail = (node *)malloc(sizeof(node));
|
||
head->rlink = tail;
|
||
tail->llink = head;
|
||
|
||
head_root = (node *)malloc(sizeof(node));
|
||
tail_root = (node *)malloc(sizeof(node));
|
||
|
||
head_root->rlink = tail_root;
|
||
tail_root->llink = head_root;
|
||
}
|
||
|
||
void read_poly(char str[] ){
|
||
int argCount ;
|
||
while (1) {
|
||
|
||
node* newNode = (node*)malloc(sizeof(node));
|
||
|
||
argCount = sscanf(str, "%dx^%d%s", &newNode->coef, &newNode->exp, str);
|
||
|
||
if (argCount >= 2) { // 成功讀取係數和指數
|
||
|
||
newNode->llink = tail->llink;
|
||
newNode->rlink = tail;
|
||
tail->llink->rlink = newNode;
|
||
tail->llink = newNode;
|
||
|
||
if (argCount == 2) {
|
||
break ;
|
||
}
|
||
|
||
} else {
|
||
if(!isdigit(newNode->coef)){
|
||
newNode->exp = 0;
|
||
|
||
newNode->llink = tail->llink;
|
||
newNode->rlink = tail;
|
||
tail->llink->rlink = newNode;
|
||
tail->llink = newNode;
|
||
|
||
break ;
|
||
|
||
}else{
|
||
// printf("newNode->coef = %d\n",newNode->coef);
|
||
// printf("isdigit(newNode->coef) = %d",isdigit(newNode->coef));
|
||
|
||
free(newNode);
|
||
break ;
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
void compact(char str[]){ /* 移除str當中的空白,使變得緊實 */
|
||
int i, j;
|
||
|
||
for (i = j = 0; str[i]; i++, j++) {
|
||
for (; str[i]==' '; i++);
|
||
str[j] = str[i];
|
||
}
|
||
str[j] = '\0';
|
||
printf("\n移除空白後的字串:%s",str);
|
||
}
|
||
|
||
void clear_node(){
|
||
// 釋放記憶體
|
||
current = head->rlink;
|
||
while (current != tail) {
|
||
temp = current;
|
||
current = current->rlink;
|
||
free(temp);
|
||
}
|
||
current_root = head_root->rlink;
|
||
while (current_root != tail_root) {
|
||
temp = current_root;
|
||
current_root = current_root->rlink;
|
||
free(temp);
|
||
}
|
||
free(head);
|
||
free(tail);
|
||
free(head_root);
|
||
free(tail_root);
|
||
}
|
||
|
||
|
||
void show( int n, int mode){
|
||
int i;
|
||
if(mode == 0){
|
||
printf("\n方程式p(x)= ");
|
||
current = head->rlink;
|
||
|
||
while (current != tail) {
|
||
if(abs(current->coef)>1){
|
||
printf("%s%d", current->coef > 1? "":"\b",current->coef);
|
||
}else if(current->coef == -1){
|
||
printf("%s", current->exp == 0? "\b-1":"\b-");
|
||
}
|
||
switch(current->exp){
|
||
case 0:
|
||
if(current->coef == 1 ) printf("1+");
|
||
else printf("+");
|
||
break;
|
||
case 1:
|
||
printf("x+");
|
||
break;
|
||
default:
|
||
printf("x^%d+",current->exp);
|
||
}
|
||
current = current->rlink;
|
||
}
|
||
printf("\b ");
|
||
|
||
}else { /* mode==1,顯示所得解 */
|
||
|
||
current_root = head_root->rlink;
|
||
|
||
while(current_root != tail_root){
|
||
printf("%d ",current_root->root);
|
||
current_root = current_root->rlink;
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
int findRoot() /* 找根,所得解存入q[],回傳根的個數 */
|
||
{
|
||
|
||
current_root = head_root->rlink;
|
||
|
||
int r, c = 0, i, j, k, sum;
|
||
int sign[2] = {1,-1};
|
||
|
||
current = tail->llink;
|
||
r = abs(current->coef); /* 取出最低階項之係數 */
|
||
|
||
if (current->exp != 0) { /* 最低階項的指數 >= 1,則0為可能解 */
|
||
if ((i = current->exp) > 0) {
|
||
node* newNode = (node*)malloc(sizeof(node));
|
||
|
||
newNode->root = 0; /* 最低階項的指數設為i */
|
||
|
||
newNode->llink = tail_root->llink;
|
||
newNode->rlink = tail_root;
|
||
tail_root->llink->rlink = newNode;
|
||
tail_root->llink = newNode;
|
||
c = 1;
|
||
}
|
||
current = head->rlink;
|
||
while(current!=tail){
|
||
current->exp -= i; /* 所有項次的指數減去i */
|
||
current = current->rlink;
|
||
}
|
||
}
|
||
|
||
|
||
// r = abs(p[2*p[0]]); /* 取出最低階項之係數 */
|
||
|
||
for (i = 1; i <= r; i++) { /* 考慮能整除r的因數i,須注意正負號 */
|
||
if (r%i != 0) continue; /* 不能整除r的i將略過,繼續考慮下一個i */
|
||
|
||
for (j = 0; j < 2; j++) { /* j為0,代表考慮+i的情境;j為1,代表考慮-i的情況 */
|
||
for (sum = 0, current = head->rlink ; current!= tail ; current = current->rlink) /* 計算每一項的結果值(係數*x^指數)並累加到sum之中 */
|
||
sum += current->coef *(int)(pow(sign[j]*i,current->exp));
|
||
if (sum == 0) {
|
||
node* newNode = (node*)malloc(sizeof(node));
|
||
newNode->root = sign[j]*i; /* bingo! 發現合乎條件的整數根,將其寫入q陣列 */
|
||
|
||
newNode->llink = tail_root->llink;
|
||
newNode->rlink = tail_root;
|
||
tail_root->llink->rlink = newNode;
|
||
tail_root->llink = newNode;
|
||
c = 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
return c;
|
||
}
|
||
|
||
void sort(){
|
||
|
||
//若沒有資料或只有一筆資料
|
||
if (head->rlink == tail || head->rlink->rlink == tail) {
|
||
return;
|
||
}
|
||
|
||
int flag = 1;
|
||
while(flag){
|
||
flag = 0;
|
||
current = head->rlink;
|
||
|
||
while(current->rlink != tail){
|
||
temp = current->rlink;
|
||
|
||
if(current->exp < temp->exp ){
|
||
temp->llink = current->llink;
|
||
current->rlink = temp->rlink;
|
||
|
||
temp->rlink->llink = current;
|
||
temp->rlink = current;
|
||
|
||
current->llink->rlink = temp;
|
||
current->llink = temp;
|
||
|
||
flag = 1;
|
||
}
|
||
else{
|
||
current = current->rlink;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
int main() {
|
||
char str[100];
|
||
int poly_num ,c , high;
|
||
init_f();
|
||
|
||
printf("\n*** 解多項式之整數根 ***\n\n輸入多項式 ==> ");
|
||
|
||
if (fgets(str, sizeof(str), stdin) == NULL) {
|
||
printf("輸入錯誤!\n");
|
||
return 1;
|
||
}
|
||
compact(str);
|
||
read_poly(str);
|
||
sort();
|
||
|
||
current = head->rlink;
|
||
high= current->exp;
|
||
|
||
show(c,0);
|
||
c = findRoot();
|
||
|
||
if (c > 0) {
|
||
printf("\n\n解得整數根為:");
|
||
show(c,1);
|
||
}
|
||
else
|
||
printf("\n\n整數根不存在\n");
|
||
clear_node();
|
||
return 0;
|
||
}
|
||
|
||
|
||
|