解一元一次整式方程的程序(可以输入括号,可以进行四则运算,由于用分数形式表示,结果是准确值)
这个程序只能解含有四则运算的一元一次整式方程,方程的输入形式要和数学上的一样,否则程序运行会出错,例如:2x+5=10, 单项式2x不能写成x2,未知数x只能写成小写。
可输入的字符包括:
数字字符: 0-9
小数点字符: .
括号字符: 小括号(),中括号[],大括号{}
等号字符: =
未知数字符: x(只能小写)
运算字符: + , - , * ,/
正号和负号字符:+ , -
除了以上字符,输入其他字符会令程序运行出错。这个程序里面没有对输入的一元一次整式方程的正确性作判断的代码,所以输入方程时必须是要正确的一元一次整式方程。(特别注意除数不能含有未知数x,否则就是分式方程了)
由于C语言的浮点数运算会存在误差,所以用分数形式表示系数和常数,结果是一个准确值。由于程序用了long long int(64位)这种数据类型,所以编译器必须要支持这种类型。
这个程序是控制台程序,是用C语言编写的。这个程序用了两种数据结构:链表和栈。思路是将方程两边的多项式变为ax+b。
编译和运行环境: Lcc-Win32 4.0 WindowsXP SP3
程序的使用: 启动程序后,按q键是退出程序,按其他键是输入方程,输入方程时不能有空格,方程输入完成后按回车键。
程序有5个文件: x_g6_m.c, x_g6.c, dsx.c, push_pop_d.c, push_pop_f.c
/*-x_g6_m.c----------------------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct k { /*定义一个结点, ax+b*/
long long int a1; /* 含有变数字母x单项式的系数 */
long long int a2;
long long int b1; /* 常数项 */
long long int b2;
struct k *next;
};
struct k x_g(char *i);
void reset(char *c);
void zeng(long long int *out1, long long int *out2);
int main()
{
struct k left, right;
char in2[202] = {'\0'};
char h2[101] = {'\0'};
long long int out1, out2;
int a, b;
printf("按q键退出程序,按其他键输入方程...\n");
for (a = 0, b = 0; 'q' != getch(); a = 0, b = 0) {
printf("输入方程: \n");
scanf("%s", in2);
while (in2[b] != '=') {
h2[a] = in2[b];
++a;
++b;
}
h2[a] = '\0';
left = x_g(h2);
++b; /*跳过'='符号*/
a = 0; /*复位a的值*/
while (in2[b] != '\0') {
h2[a] = in2[b];
++a;
++b;
}
h2[a] = '\0';
right = x_g(h2);
/*
printf("%ld %ld\n", left.a1, left.a2);
printf("%ld %ld\n", left.b1, left.b2);
getch();
printf("%ld %ld\n", right.a1, right.a2);
printf("%ld %ld\n", right.b1, right.b2);
getch();
*/
/*-----------------------------------------------*/
/* ax=b */
/*求公分母*/
left.a1 = left.a1 * right.a2;
right.a1 = right.a1 * left.a2;
left.a2 = right.a2 = left.a2 * right.a2;
left.a1 = left.a1 - right.a1;
/*--------------------------------------*/
/*ax=b中的b的值*/
left.b1 = left.b1 * right.b2;
right.b1 = right.b1 * left.b2;
right.b2 = left.b2 = left.b2 * right.b2;
right.b1 = right.b1 - left.b1;
/*---------------------------------------*/
out1 = right.b1 * left.a2; /*分子*/
out2 = right.b2 * left.a1; /*分母*/
zeng(&out1, &out2);
printf("真分数或假分数形式(准确值): x = %lld / %lld\n", out1, out2);
printf("小数形式(准确值或近似值): x = %Lf\n", (long double)out1 / (long double)out2);
printf("按q键退出程序,按其他键输入方程...\n");
reset(in2); /*复位存储输入方程的in2数组*/
}
return 0;
}
void reset(char *c)
{
int w = 0;
while (w < 202) {
*c = '\0';
++c;
++w;
}
}
void zeng(long long int *out1, long long int *out2)
{
long long int s1, s2;
int i;
s1 = *out1;
s2 = *out2;
for (i = 2; i <= 9;) { /*求最简分数,对分子和分母进行约分*/
if (s1 % i == 0 && s2 % i == 0) {
s1 = s1 / i;
s2 = s2 / i;
i = 2;
continue;
}
++i;
}
if (s1 < 0 && s2 < 0) {
s1 = s1 * -1;
s2 = s2 * -1;
}
*out1 = s1;
*out2 = s2;
}
/*------------------------------------------------------------------------------------------------------*/
/*-x_g6.c------------------------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
struct k { /*定义一个结点, ax+b*/
long long int a1; /* 含有变数字母x单项式的系数 */
long long int a2;
long long int b1; /* 常数项 */
long long int b2;
struct k *next;
};
struct y {
char c;
struct y *next;
};
struct kk { /*定义一个结构, ax+b*/
long long int a1; /* 含有变数字母x单项式的系数 */
long long int a2;
long long int b1; /* 常数项 */
long long int b2;
};
struct z {
char c;
struct z *next;
};
struct xj {
long long int m;
long long int n;
};
/*--------------------------------------------------*/
int myisdigit(char c);
void pushd(struct kk);
struct kk popd(void);
void pushf(char);
char popf(void);
struct kk newfen(char *c);
int is1(char c);
void reset_dan(char *c);
void call();
struct k dsx(struct k *head, struct y *head2);
struct xj xtoj(char *c);
long long int atoll(char *s);
struct k x_g(char *i)
{
struct z *head, *p, *q;
struct k *head1, *p1, *q1, temp1;
struct y *head2 = NULL, *p2, *q2; /*head2是指向运算符号的链表头指针,运算符号的个数有可能是零*/
struct kk kk_temp;
char h[101] = {'\0'}; /*方程左边或右边的多项式*/
char dan[16] = {'\0'};
char c = '\0', c2 = 'a';
int w = 0;
while ((h[w] = *i)!= '\0') {
++w;
++i;
}
/*先建立字符链表--------------------------------------------------------------*/
w = 0;
for (p = (struct z *)malloc(sizeof(struct z)), head = p; h[w] != '\0'; ) {
p->c = h[w];
if (h[++w] == '\0') { /*最后一个结点*/
p->next = NULL;
break;
}
p = p->next = (struct z *)malloc(sizeof(struct z));
}
/*------------------------------------------------------------------------------*/
/*插入'*'号------------------------------------------------------------------------------*/
for (p = head; p != NULL; p = p->next) { /*对左括号进行处理*/
if (p->next == NULL)
break;
if ((p->next)->c == '(' || (p->next)->c == '[' || (p->next)->c == '{') {
if ( myisdigit(p->c) ) {
q = p->next;
p->next = (struct z *)malloc(sizeof(struct z));
(p->next)->c = '*';
(p->next)->next = q;
}
else if (p->c == 'x') {
q = p->next;
p->next = (struct z *)malloc(sizeof(struct z));
(p->next)->c = '*';
(p->next)->next = q;
}
else if (p->c == ')' || p->c == ']' || p->c == '}') {
q = p->next;
p->next = (struct z *)malloc(sizeof(struct z));
(p->next)->c = '*';
(p->next)->next = q;
}
}
}
/*----------------------------------------------------------------------*/
for (p = head; p != NULL; p = p->next) { /*对右括号进行处理*/
if (p->next == NULL)
break;
if (p->c == ')' || p->c == ']' || p->c == '}') {
if (myisdigit((p->next)->c)) {
q = p->next;
p->next = (struct z *)malloc(sizeof(struct z));
(p->next)->c = '*';
(p->next)->next = q;
}
else if ((p->next)->c == 'x') {
q = p->next;
p->next = (struct z *)malloc(sizeof(struct z));
(p->next)->c = '*';
(p->next)->next = q;
}
else if ((p->next)->c == '(' || (p->next)->c == '[' || (p->next)->c == '{') {
q = p->next;
p->next = (struct z *)malloc(sizeof(struct z));
(p->next)->c = '*';
(p->next)->next = q;
}
}
}
/*--------------------------------------------------------------------------------*/
/*经以上处理后省略的乘号已恢复*/
/*插入字符'0',去除多项式的正号和负号---------------------------------------------*/
if (head->c == '+' || head->c == '-') { /* 如果链表第一个字符是'+'