#include "stdio.h" #define size 128 //sum[0]視為第0位, sum[1]第1位 依此類推 //例如若這陣列記14547,則sum[4] ~ sum[0]分別是1,4,5,4,7 int sum[size] = {0}; void Double() { //就是把sum陣列這個長整數的值加倍,我的算法是自己加自己 int i; int carry = 0; //代表有進位 for (i = 0; i < size; i ++) { //i = 0 時,carry為0,因為第一位不會有進位 //i > 0 時,carry 值為 //當sum[i-1]+sum[i-1]加前一個carry>=10時就設為1,不是則為0 //例如計算38+38,sum[0]的值為先算完sum[0]+sum[0]=16, //而16>10,所以設carry = 1及sum[0] = 16-10 = 6 //接著sum[1]的值為sum[1]+sum[1]+carry = 3 + 3 + 1 = 7 sum[i] = sum[i] + sum[i] + carry; if (sum[i] >= 10) { //若這位數的和大於等於10,代表有進位, //這一位要減10,而下一位要多加1, carry = 1; sum[i] -= 10 ; } else carry = 0; } } void Add1() { //就是把sum陣列的值 + 1, //例如136變137,其中sum[2] = 1, sum[1] = 3, sum[0] = 6, //變sum[2] = 1, sum[1] = 3, sum[0] = 7 //或39變40,其中sum[1] = 3, sum[0] = 9, //變sum[1] = 4, sum[0] = 0 int i = 0; int carry = 0; sum[0] ++; if ( sum[0] == 10) { //加1後若有進位,則只可能是10 //於是carry為1,sum[0]值就為尾數0, carry = 1; sum[0] = 0; } //若carry不是1,則結尾加1後,就完成了加1; //是的話,則要從第二位起繼續加。例如99+1=100,sum[1]和sum[2]也跟著變 while ( carry == 1) { //遇到結尾是9, 99, 或9999...時,才會跑進這while i++; //代表再走到下一位 sum[i] ++; //表示這一位多加carry值1,所以sum[i]++ if (sum[i] == 10) { //若還繼續進位的話,就會繼續維持carry = 1,sum[i]這位則變為9+1-10=0 sum[i] = 0; } else break; //表示沒繼續進位,也完成了這個數加1 } } int main() { int i; char str[size]; int weisu; printf("請輸入二進位數字字串(例如01001)\n"); scanf("%[0-1]", str); //也可把[0-1]改成d for (i = 0 ; i < size ; i++) { if (str[i] == '\0') break; Double(); //把sum陣列的值加倍 if (str[i] == '1') Add1(); //是1的話就多加1,不是的話就不用 } //weisu代表sum陣列代表的數的最高位。 //例如若輸入為11001,sum代表值就會是25 (sum[1] = 2, sum[0] = 5), //而weisu 會等於 1 weisu = size - 1; //從size-1位開始,找到真正的weisu //例如sum陣列從最高位起為00...0015, //就從最高位起開始找,直到遇到的第一個不是0的位數時停下來 //此處就代表sum的weisu while (sum[weisu] == 0 && weisu >= 0) weisu--; printf("這個二進位數字的十進位為:"); if (weisu == -1) printf("0\n"); //沒有sum[-1],但若遇到weisu = -1則sum代表的值必是0 else { //從最高位印到第0位 for (i = weisu; i >= 0 ; i --) printf("%d", sum[i]); printf("\n"); } system("pause"); return 0; }
This blog contains posts regarding my practice in programming. The posts are about questions in Yahoo Knowledge or some program design ideas or implementation of algorithms.
Friday, January 13, 2012
利用C語言寫出長整數2進位轉10進位
Monday, January 9, 2012
C++的getline與以strtok作字串分割
以下程式可以以getline輸入加法的字串,例如"1.1 + 2 + 3.5 + 4",輸出為這幾個數的和。方法就是以strtok分割字串,然後以atof轉成數值,然後把值將加後,最後得到結果
#include "iostream" #include "stdlib.h" #include "string.h" #include "stdio.h" using namespace std; int main() { char str[256]; cout << "請輸入加法運算字串,例如1.1 + 2 + 3.5 + 4 : \n"; cin.getline(str, 100); char *delim = "+"; char * pch; int i = 0, j; double answer = 0; double values[4]; pch = strtok(str, delim); while (pch != NULL) { values[i] = atof(pch); cout << "values[i] = " << values[i] << endl; pch = strtok(NULL, delim); i++; } for ( j = 0 ; j < i ; j ++) answer = answer + values[j]; cout << "這" << i << "個數的和為" << answer << endl; system("pause"); return 0; }
Sunday, January 8, 2012
以Prim's Algorithm來求最小成本擴張樹
#include "stdafx.h" #include <iostream> #include <stdio.h> #define INF 10000000 using namespace std; //一個undirected graph的adjacency matrix int adjMatrix[8][8] = { {0, 300, 1000, INF, INF, INF, INF, 1700}, {300, 0, 800, INF, INF, INF, INF, INF}, {1000, 800, 0, 1200, INF, INF, INF, INF}, {INF, INF, 1200, 0, 1500, 1000, INF, INF}, {INF, INF, INF, 1500, 0, 250, INF, INF}, {INF, INF, INF, 1000, 250, 0, 900, 1400}, {INF, INF, INF, INF, INF, 900, 0, 1000}, {1700, INF, INF, INF, INF, 1400, 1000, 0}, }; int addedVertices[8] = {0}; int addedVerticesNum = 1; //紀錄成為spanning tree的各邊中其中一點的數目數目。第一個點為0 bool isAdded(int v) { //檢驗這個點是不是已被加入spanning tree的邊中其中一個點 for (int i = 0 ; i < addedVerticesNum; i ++) { if (addedVertices[i] == v) return true; } return false; } //紀錄會成為spanning tree的7條邊。若頂點數目是n則是n-1條邊 struct Edge { int node1; int node2; } edge[7]; int main(int argc, char* argv[]) { int p1, p2; //紀錄被檢驗的邊的兩點 int lowestWeight; //在下面的三層迴圈中,暫存與已被加入spanning tree的邊相連的邊中,weight最低的 int thep1, thep2; //紀錄這一次要被加入minimum cost spanning tree的邊的兩個頂點 for (int i = 0 ; i < 8 ; i ++) { lowestWeight = INF; for (int count = 0; count < addedVerticesNum; count++) { //從幾個已被加的點開始找 p1 = addedVertices[count]; for (p2 = 0; p2 < 8 ; p2++) { if ( p2 != p1 && adjMatrix[p1][p2] < lowestWeight && !isAdded(p2) ) { //這個要被加入spanninf tree的邊的兩個點不同,所以 p2 != p1 //兩個點之間須有邊相連,所以 adjMatrix[p1][p2] < INF。 //adjMatrix[p1][p2] < lowestWeight則是為了找出權重最低的邊 //在加一條新的邊時,依prim的演算法必須一點是已被加入spanning tree的邊中的其中一點,另一點不是。 //而p1 = addedVertices[count] 和 !isAdded(p2)代表p1是其中一點,p2不是 lowestWeight = adjMatrix[p1][p2]; thep1 = p1; thep2 = p2; } } } if (lowestWeight < INF) { edge[addedVerticesNum - 1].node1 = thep1; edge[addedVerticesNum - 1].node2 = thep2; //thep1是新加入spanning tree的邊中,已和其中一條被加入spanning tree的邊相連的點, //thep2則是尚未與被加入spanning tree的邊相連的另一點 addedVertices[addedVerticesNum] = thep2; addedVerticesNum++; } else //若lowestWeight = INF,表示p1未與其他任何點相連,所以整個圖必定沒有spanning tree break; } if (addedVerticesNum < 8 ) cout << "No spanning tree\n"; else { cout << "The edges of the spanning tree are:\n"; for (int i = 0 ; i < 7; i++ ) cout << "edge " << edge[i].node1 << edge[i].node2 << endl; } //以文章最上面的圖為例,就會輸出 //the edges of the spanning tree are: //edge 01 //edge 12 //edge 23 //edge 35 //edge 54 //edge 56 //edge 67 system("PAUSE"); return 0; }
Monday, January 2, 2012
C++ 二元樹的刪除節點
#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
using namespace
std;
struct node
{
int
data;
struct
node *left; // self-reference linker
struct
node *right; // self-reference linker
} *root, *tree, *t;
struct node *GetSmallest(struct node *ptr)
{
while (ptr->left != NULL)
ptr=ptr->left;
return ptr;
}
struct node *Delete(struct
node *ptr, int value)
{
//從維基百科知,There are three possible cases to
consider:
// 1.
Deleting a leaf (node with no children): Deleting a leaf is easy, as we can
simply remove it from the tree.
// 2.
Deleting a node with one child: Remove the node and replace it with its child.
// 3.
Deleting a node with two children: Call the node to be deleted N. Do not delete
N.
// Instead, choose either its in-order successor
node or its in-order predecessor node, R.
// Replace
the value of N with the value of R, then delete R.
//第一和和第二種情形的刪除很容易,第種情形時的刪除,我是用「中序立即後繼節點(inorder
immediate successor)」法,
//就是將欲刪除節點的右子樹最小者向上提。詳細可參閱網路上搜尋的介紹
struct node *temp;
if (ptr!= NULL)
{
////第一種情形
if (ptr->right == NULL && ptr->left ==
NULL)
ptr=
NULL;
///////////
//第二種情形
else if (ptr->left
== NULL)
ptr
= ptr->right;
else if
(ptr->right == NULL)
ptr
= ptr->left;
//////////
else if (value >
ptr->data)
ptr->right
= Delete(ptr->right, value);
else if (value <
ptr->data)
ptr->left
= Delete(ptr->left, value);
////////
//第三種情形
else
{
temp
= GetSmallest(ptr->right);
temp->left
= ptr->left;
ptr
= ptr->right;
}
/////////
}
else
cout
<< "Sorry, the input does not match any
node's value in the tree.\n";
return ptr;
}
int main(int
argc, char* argv[])
{
int
i, key;
root = NULL;
for
(i = 0; i < 6; i++)
{
cout
<< "Enter number " <<
i+1 << " > " ;
cin
>> key;
if (root == NULL) // 插入第一個數字
{
root
= new struct
node;
root->data
= key;
root->left
= root->right = NULL;
}
else // 插入第二個以後的數字
{
tree
= root;
while (tree != NULL)
{
if (key == tree->data) // 要插入的數字已經存在於樹中
{
cout
<< "duplicate node!";
break;
}
else if (key <
tree->data) // 要插入的數字< 節點數字, 向左子樹移動
{
if (tree->left != NULL)
tree
= tree->left; // 向左子樹移動
else // 沒有左子樹時, 則新增節點, 放置要插入的數字
{
t
= new struct
node;
t->data
= key;
t->left
= t->right = NULL;
tree->left
= t;
break;
}
}
else // 要插入的數字> 節點數字, 向右子樹移動
{
if (tree->right != NULL)
tree
= tree->right; // 向右子樹移動
else // 沒有右子樹時, 則新增節點, 放置要插入的數字
{
t
= new struct
node;
t->data
= key;
t->left
= t->right = NULL;
tree->right
= t;
break;
}
}
}
}
}
cout
<< "root->left->left->data =
" << root->left->left->data << endl;
Delete(root,
0);
cout
<< "root->left->data = "
<< root->left->data << endl;
if (root->left->left == NULL)
cout
<< "root->left->left == NULL";
//例如插入3 1 4 0 2 5 ,經Delete(root,
0)後,就會發現被刪掉了
system("pause");
return
0; // 設置中斷點, 察看樹的形狀
}
Sunday, January 1, 2012
複數的加減乘除的C++類別與程式
// Complex.cpp #include "StdAfx.h" #include "Complex.h" #include <iostream> using namespace std; Complex::Complex(double r, double i) { real = r; imaginary = i; } Complex::~Complex(void) { } void Complex::Add(Complex &c) { real += c.real; imaginary += c.imaginary; } void Complex::Subtract(Complex &c) { real -= c.real; imaginary -= c.imaginary; } void Complex::Multiply(Complex &c) { real = real * c.real - imaginary * c.imaginary; imaginary = real * c.imaginary + imaginary * c.real; } void Complex::Divide(Complex &c) { if ( c.real != 0 || c.imaginary != 0) { double fenmu = c.real * c.real + c.imaginary * c.imaginary; real = real * c.real + imaginary * c.imaginary; real /= fenmu; imaginary = imaginary * c.real - real * c.imaginary; imaginary / fenmu; } else { cout << "Cannot divide a number by zero.\n"; } } void Complex::OutputValue() { if (real == 0 && imaginary == 0) cout << "0\n"; else if (real == 0) { if (imaginary > 0) cout << imaginary << "*i\n"; else cout << -imaginary << "*i\n"; } else if (imaginary == 0) cout << real << "\n"; else { if (imaginary > 0) cout << real << " + " << imaginary << "*i\n"; else cout << real << " - " << -imaginary << "*i\n"; } }
//Complex.h #pragma once class Complex { public: Complex(double = 0, double = 0); ~Complex(void); void Add(Complex &); void Subtract(Complex &); void Multiply(Complex &); void Divide(Complex &); void OutputValue(); private: float real; float imaginary; };
// main.cpp : // #include "stdafx.h" #include <stdlib.h> #include "Complex.h" #include <iostream> #include <ctype.h> #define size 12 using namespace std; bool IsDouble(char a[]) { int i; int pointsNum = 0; if ( !isdigit(a[0]) && a[0] != '-' && a[0] != '.') return false; if (a[0] == '.') pointsNum = 1; for (i = 1; i < size, a[i] != '\0' ; i ++ ) { if ( !isdigit(a[i]) && a[i] != '.') return false; else if (a[i] == '.') pointsNum ++; } if (pointsNum <= 1 && i < 12) return true; } int _tmain(int argc, _TCHAR* argv[]) { char rr[size], ii[size]; double r, i; cout << "Enter complex number c1.\n"; cout << "real part: "; cin >> rr; while (!IsDouble(rr)) { cout << "Sorry, please input a real number"; cin >> rr; } r = atof(rr); cout << "imaginary part: "; cin >> ii; while (!IsDouble(ii)) { cout << "Sorry, please input a real number"; cin >> ii; } i = atof(ii); Complex c1(r, i); ////////// cout << "Enter complex number c2.\n"; cout << "real part: "; cin >> rr; while (!IsDouble(rr)) { cout << "Sorry, please input a real number"; cin >> rr; } r = atof(rr); cout << "imaginary part: "; cin >> ii; while (!IsDouble(ii)) { cout << "Sorry, please input a real number"; cin >> ii; } i = atof(ii); Complex c2(r, i); /////// Complex tempc1, tempc2; tempc1 = c1; tempc2 = c2; cout << "\nThe value c1 + c2 is :"; c1.Add(c2); c1.OutputValue(); ///////// c1 = tempc1; c2 = tempc2; cout << "\nThe value c1 - c2 is :"; c1.Subtract(c2); c1.OutputValue(); ///////// c1 = tempc1; c2 = tempc2; cout << "\nThe value c1 * c2 is :"; c1.Multiply(c2); c1.OutputValue(); ///////// c1 = tempc1; c2 = tempc2; cout << "\nThe value c1 / c2 is :"; c1.Divide(c2); c1.OutputValue(); ///////// c1 = tempc1; c2 = tempc2; system("pause"); return 0; }
C++ [泡沫排序] [ 模擬提款機]
//第一題: // CPPTest.cpp : 定義主控台應用程式的進入點。 // #include "stdafx.h" #include<iomanip> #include<iostream> #include<stdlib.h> #include<time.h> using namespace std; void BubbleSort(int num) { int* ptr = new int[num]; for (int i = 0; i < num; i ++) { cout << "Enter number " << i+1 << " > " ; cin >> ptr[i]; } int temp; for (int i = 0; i < num; i ++) { for (int j = i+1; j < num ; j++) { if (ptr[i] > ptr[j]) { temp = ptr[i]; ptr[i]=ptr[j]; ptr[j]=temp; } } } cout << "The sorted numbers in ascending order are: \n"; for (int i = 0; i < num; i ++) { cout << ptr[i]; cout << " "; } } int _tmain(int argc, _TCHAR* argv[]) { int num; cout << "Enter the number of inegers: "; cin >> num; BubbleSort(num); system("pause"); return 0; } ----- //第二題: // CPPTest.cpp : 定義主控台應用程式的進入點。 // #include "stdafx.h" #include<iomanip> #include<iostream> #include<fstream> #include<stdlib.h> #include<cstring> #define size 15 using namespace std; int _tmain(int argc, _TCHAR* argv[]) { int money; int deposition, withdrawal; int choice; fstream file; while(true) { cout << "(1)Balance Check \n"; cout << "(2)Withdraw \n"; cout << "(3)Deposit \n"; cout << "(4)Clear \n"; cout << "(5)Exit \n"; cout << "Please choose a service: "; cin >> choice; if (choice == 1) { ifstream fin("money.txt", ios::in); fin >> money; cout << "The balance in your account is : " << money << " dollars.\n\n"; } else if (choice == 2) { ifstream fin("money.txt"); fin >> money; cout << "Enter the amount of money you withdraw: "; cin >> withdrawal; if (withdrawal <= money) { ofstream fout("money.txt", ios::trunc); fout << money - withdrawal; cout << "The balance in your account now is : " << money - withdrawal << " dollars\n\n"; } else { cout << "The balance in your account now is only " << money << " dollars and not enough to withdraw " << withdrawal << " dollars.\n\n"; } } else if (choice == 3) { ifstream fin("money.txt"); fin >> money; cout << "Enter the amount of money you deposit: "; cin >> deposition; ofstream fout("money.txt", ios::trunc); fout << money + deposition; cout << "The balance in your account now is : " << money + deposition << " dollars.\n\n"; } else if (choice == 4) { ofstream fout("money.txt", ios::trunc); fout << 0; cout << "The balance in your account now is 0 dollar.\n\n"; } else if (choice == 5 ) { break; } } "pause"); return 0; }
Subscribe to:
Posts (Atom)