大整数乘法
2011年7月31日 16:37 | Comments(4) | Category:C++ | Tags:c++ 高精度
#include <iostream> #include <memory> using namespace std; int* multi(int* num1, int size1, int* num2, int size2) { int size = size1 + size2; int* ret = new int[size]; int i = 0; memset(ret, 0, sizeof(int)*size); //先把两数组分别相乘 for(i = 0; i < size2; ++i) { int k = i; for(int j = 0; j < size1; ++j) { ret[k++] += num2[i]*num1[j]; } } //进位 for(i = 0; i < size; ++i) { if(ret[i] >= 10) { //加上进位 ret[i+1] += ret[i] / 10; //只留个位 ret[i] %= 10; } } return ret; } int main(int argc, char *argv[]) { int num1[] = {1,2,3,4,5,6,7,8,9,1,1,1,1,1}; int num2[] = {1,1,1,2,2,2,3,3,3,4,4,4,5,5}; int* ret = multi(num1, 14, num2, 14); for(int i = 27; i >= 0; i--) { cout << ret[i]; } delete[] ret; return 0; }
计算11111987654321*55444333222111=616096746266157102781891631
BrainFuck解释器
2011年2月01日 08:57 | Comments(19) | Category:C语言 | Tags:c BrainFuck 解释器
无注释版本:
#include <stdio.h> #include <stdlib.h> #define SIZE 5000 char data[SIZE], code[SIZE]; int ptr, flag; void interpreter(char *ip) { char* re; while (*ip) { switch(*ip++) { case '<': --ptr; break; case '>': ++ptr; break; case '+': ++data[ptr]; break; case '-': --data[ptr]; break; case '.': putchar(data[ptr]); fflush(stdout); break; case ',': data[ptr] = getchar(); fflush(stdout); break; case '[': for (flag=1,re=ip; flag && *ip; ++ip) flag += *ip=='[', flag -= *ip==']'; if(!flag) { ip[-1] = 0; while (data[ptr]) interpreter(re); ip[-1] = ']'; break; } case ']': puts("Unbalancded brackets!"), exit(-3); default : ;//SKIP } if (ptr < 0 || ptr > 100) puts("Out of Range"), exit(-4); } } int main(int argc, char *argv[]) { FILE *fin; int codelength; if (argc != 2) return puts("BrainFuck Interpreter v 0.1\nStar\nUsage:BFI filename"), 0; if ((fin = fopen(argv[1], "r")) == NULL) return puts("Cannot open file!"), -1; fseek(fin, 0, SEEK_END); if ((codelength = ftell(fin)) > SIZE) return puts("The program is too large."), -2; fseek(fin, 0, SEEK_SET); fread(code, codelength, 1, fin); code[codelength] = '\0'; interpreter(code); return 0; }
Windows进程管理实验
2011年1月25日 04:31 | Comments(87) | Category:Windows | Tags:操作系统 进程 线程 互斥 同步 信号量 临界区 命名管道
1.线程的创建与撤销
#include <windows.h> #include <stdio.h> void func(); static HANDLE h1 = NULL; static HANDLE hHandle1 = NULL; int main(INT argc, TCHAR* argv[]) { int nRetCode = 0; DWORD dwThreadID1; DWORD dRes, err; //创建一个信号量 hHandle1 = CreateSemaphore(NULL, 0, 1, "SemaphoreName1"); if (hHandle1 == NULL) puts("Semaphore Create Fail!"); else puts("Semaphore Create Success!"); //打开信号量 hHandle1 = OpenSemaphore(SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, NULL, "SemaphoreName1"); if (hHandle1 == NULL) puts("Semaphore Open Fail!"); else puts("Semaphore Open Success!"); //创建子线程 h1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, NULL, 0, &dwThreadID1); if (h1 == NULL) puts("Thread1 create Fail!"); else puts("Thread1 create Success!"); //主线程等待子线程结束 dRes = WaitForSingleObject(hHandle1, INFINITE); err = GetLastError(); printf("WaitForSingleObject err = %d\n", err); if(dRes == WAIT_TIMEOUT) printf("TIMEOUT!dRes = %d\n", dRes); else if(dRes == WAIT_OBJECT_0) printf("WAIT_OBJECT!dRes = %d\n", dRes); else if(dRes == WAIT_ABANDONED) printf("WAIT_ABANDONED!dRes = %d\n", dRes); else printf("dRes = %d\n", dRes); CloseHandle(h1); CloseHandle(hHandle1); ExitThread(0); return nRetCode; } void func() //线程函数 { BOOL rc; DWORD err; puts(" NOW IN THREAD!"); //子线程焕醒主线程,此时同步执行 rc = ReleaseSemaphore(hHandle1, 1, NULL); err = GetLastError(); printf("ReleaseSemaphore err = %d\n", err); if (rc == 0) puts("ReleaseSemaphore Fail!"); else printf("ReleaseSemaphore Success! rc = %d\n", rc); }
2.线程的同步
#include <windows.h> #include <stdio.h> void ThreadName1(); static HANDLE hHandle1 = NULL; DWORD dwThreadID1; int main(INT argc, TCHAR* argv[]) { int nRetCode = 0; //创建一个线程 hHandle1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadName1, NULL, 0, &dwThreadID1); //挂起5秒 Sleep(5000); CloseHandle(hHandle1); //撤消线程 ExitThread(0); return nRetCode; } void ThreadName1() //线程函数 { printf("Thread is Running!\n"); }
3.线程的互斥
#include <windows.h> #include <stdio.h> static INT count = 5; static HANDLE h1, h2; LPCRITICAL_SECTION hCriticalSection; CRITICAL_SECTION Critical; void func1(); void func2(); int main(INT argc, TCHAR* argv[]) { int nRetCode = 0; DWORD dwThreadID1, dwThreadID2; //指向临界区 hCriticalSection = &Critical; InitializeCriticalSection(hCriticalSection); //创建线程1 h1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func1, NULL, 0, &dwThreadID1); if (h1 == NULL) puts("Thread1 create Fail!"); else puts("Thread1 create Success!"); //创建线程 h2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func2, NULL, 0, &dwThreadID1); if (h2 == NULL) puts("Thread2 create Fail!"); else puts("Thread2 create Success!"); Sleep(1000); //回收处理 CloseHandle(h1); CloseHandle(h2); DeleteCriticalSection(hCriticalSection); ExitThread(0); return nRetCode; } void func1() //线程函数1 { int r1; //进入临界区 EnterCriticalSection(hCriticalSection); r1 = count; Sleep(500); ++r1; count = r1; printf("count in func1 = %d\n", count); //退出临界区 LeaveCriticalSection(hCriticalSection); } void func2() //线程函数2 { int r2; EnterCriticalSection(hCriticalSection); r2 = count; Sleep(500); ++r2; count = r2; printf("count in func2 = %d\n", count); LeaveCriticalSection(hCriticalSection); }
4.使用命名管道实现进程通信
服务端
//Server.c #include <windows.h> int main(void) { INT nRetCode = 0; INT err; BOOL rc; HANDLE hPipeHandle1; CHAR lpName[] = "\\\\.\\pipe\\myPipe"; CHAR InBuffer[50] = ""; CHAR OutBuffer[50] = ""; DWORD BytesRead, BytesWrite; //创建一个命名管道 hPipeHandle1 = CreateNamedPipe((LPCTSTR)lpName, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_DAC , PIPE_TYPE_MESSAGE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 20, 30, NMPWAIT_USE_DEFAULT_WAIT, NULL); if((hPipeHandle1 == INVALID_HANDLE_VALUE) || (hPipeHandle1 == NULL)) { err = GetLastError(); printf("Server Pipe Create Fail! err = %d\n", err); exit(1); } else puts("Server Pipe Create Success!"); while(TRUE) { //连接命名管道 rc = ConnectNamedPipe(hPipeHandle1, NULL); if (rc == 0) { err = GetLastError(); printf("Server Pipe Connect Fail! err = %d\n", err); exit(2); } else puts("Server Pipe Connect Success!"); strcpy(InBuffer, ""); strcpy(OutBuffer, ""); //向命名管道中读数据 rc = ReadFile(hPipeHandle1, InBuffer, sizeof(InBuffer), &BytesRead, NULL); if (rc == 0 && BytesRead == 0) { err = GetLastError(); printf("Server Read Pipe Fail! err = %d\n", err); exit(2); } else printf("Server Read Pipe Success!\nDATA from Client is = %s\n", InBuffer); rc = strcmp(InBuffer, "end"); if (rc == 0) break; puts("Please Input Data to Send"); scanf("%s", OutBuffer); //向命名管道中写数据 rc = WriteFile(hPipeHandle1, OutBuffer, sizeof(OutBuffer), &BytesWrite, NULL); if (rc == 0) puts("Server Write Pipe Fail!"); else puts("Server Write Pipe Success!"); //拆除与命名管道的连接 DisconnectNamedPipe(hPipeHandle1); rc = strcmp(OutBuffer, "end"); if (rc == 0) break; } puts("Now Server be END!"); CloseHandle(hPipeHandle1); return nRetCode; }
客户端
//Clinet.c #include <windows.h> int main(void) { INT nRetCode = 0; INT err = 0; BOOL rc = 0; CHAR lpName[] = "\\\\.\\pipe\\myPipe"; CHAR InBuffer[50] = ""; CHAR OutBuffer[50] = ""; DWORD BytesRead; while(TRUE) { strcpy(InBuffer, ""); strcpy(OutBuffer, ""); puts("Input Data Please!"); scanf("%s", InBuffer); rc = strcmp(InBuffer, "end"); if (rc == 0) { //连接命名管道 rc = CallNamedPipe(lpName, InBuffer, sizeof(InBuffer), OutBuffer, sizeof(OutBuffer), &BytesRead, NMPWAIT_USE_DEFAULT_WAIT); break; } //等待命名管道 rc = WaitNamedPipe(lpName, NMPWAIT_WAIT_FOREVER); if (rc == 0) { err = GetLastError(); printf("Wait Pipe Fail! err = %d\n", err); exit(1); } else puts("Wait Pipe Success!"); rc = CallNamedPipe(lpName, InBuffer, sizeof(InBuffer), OutBuffer, sizeof(OutBuffer), &BytesRead, NMPWAIT_USE_DEFAULT_WAIT); rc = strcmp(OutBuffer, "end"); if (rc == 0) break; if (rc == 0) { err = GetLastError(); printf("Pipe Call Fail! err = %d\n", err); exit(1); } else printf("Pipe Call Success!\nData from Server is %s\n", OutBuffer); } puts("Now Client to be End!"); return nRetCode; }
Windows屏幕飘雪
2011年1月23日 07:46 | Comments(10) | Category:Windows | Tags:Windows API SDK c
#include <windows.h> #include <stdlib.h> #define UNICODE //使用UNICODE字符 #define _UNICODE #define ID_TIME 1 #define NUMOFSNOW 214 //雪花数量 typedef struct tagSNOW { POINT pos; //雪花坐标 int r; //雪花半径 int xSpeed; //x,y速度 int ySpeed; }SNOW, *PSNOW; INT screen_x, screen_y; //屏幕坐标 #pragma comment(linker, "/subsystem: windows") LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) { TCHAR szAppName[] = TEXT ("屏幕飘雪"); //应用程序名 TCHAR szTitle[] = TEXT ("桌面窗口"); //窗口名 HWND hWnd; //窗口句柄 MSG msg; //消息循环 WNDCLASS wc; //窗口类 INT x, y; wc.cbClsExtra = 0; //不用额外窗口类和窗口空间 wc.cbWndExtra = 0; wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH); //黑色背景 wc.hCursor = LoadCursor (hInstance, IDC_ARROW); //默认箭头 wc.hIcon = LoadIcon (hInstance, IDI_APPLICATION); //默认图标 wc.hInstance = hInstance; //程序句柄 wc.lpfnWndProc = WndProc; //窗口过程 wc.lpszClassName = szAppName; //程序名称 wc.lpszMenuName = NULL; //菜单置空 wc.style = CS_HREDRAW | CS_VREDRAW; //水平|垂直对齐 if (!RegisterClass (&wc)) { MessageBox (NULL, TEXT("窗口注册失败!"), TEXT("ERROR"), MB_OK | MB_ICONINFORMATION); return -1; } screen_x = GetSystemMetrics (SM_CXSCREEN); screen_y = GetSystemMetrics (SM_CYSCREEN); hWnd = CreateWindow (szAppName, szTitle, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, screen_x, screen_y, NULL, NULL, hInstance, NULL); if (!hWnd) { MessageBox (NULL, TEXT("创建窗口失败!"), TEXT("ERROR"), MB_OK | MB_ICONINFORMATION); return -2; } SetWindowPos (hWnd, HWND_TOPMOST, 0, 0, screen_x, screen_y, SWP_NOMOVE); while (GetMessage (&msg, NULL, 0, 0) > 0) { TranslateMessage (&msg); DispatchMessage (&msg); } return msg.wParam; } LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HDC hScrDC, hSaveDC, hMemDC; static HBITMAP hSaveBmp, hBmp; static SNOW snows[NUMOFSNOW]; static RECT rtScr; INT i; switch (message) { case WM_CREATE: //创造窗口时 { hScrDC = CreateDC ("DISPLAY", NULL, NULL, NULL); //召唤2个DC,并以此为祭品,召唤2个BMP hSaveDC = CreateCompatibleDC(hScrDC); hMemDC = CreateCompatibleDC(hScrDC); hSaveBmp = CreateCompatibleBitmap(hScrDC, screen_x, screen_y); hBmp = CreateCompatibleBitmap(hScrDC, screen_x, screen_y); SelectObject (hSaveDC, hSaveBmp); SelectObject (hMemDC , hBmp); //将屏幕拷贝到SAVE BitBlt (hSaveDC, 0, 0, screen_x, screen_y, hScrDC, 0, 0, SRCCOPY); SetRect (&rtScr, 0, 0, screen_x, screen_y); srand ((unsigned)GetTickCount()); //随机变量数据 for (i = 0; i < NUMOFSNOW; ++i) { snows[i].pos.x = rand() % screen_x; snows[i].pos.y = rand() % (screen_y / 3); //屏幕1/3以上召唤雪 snows[i].r = rand() % 4 + 1; //1~4 snows[i].xSpeed = rand() % 2 - 1; //0~1 snows[i].ySpeed = rand() % 4 + 2; //2~4 } ShowCursor (FALSE); SetTimer (hWnd, ID_TIME, 12, NULL); } break; case WM_TIMER: { for(i = 0; i < NUMOFSNOW; ++i) { snows[i].pos.x += snows[i].xSpeed; //移动 snows[i].pos.y += snows[i].ySpeed; if (!PtInRect (&rtScr, snows[i].pos)) //如果跑出屏幕外 { snows[i].pos.x = rand() % screen_x; snows[i].pos.y = rand() % (screen_y / 3); } } //将存好的放入内存中 BitBlt (hMemDC, 0, 0, screen_x, screen_y, hSaveDC, 0, 0, SRCCOPY); //创建雪 for(i = 0; i < NUMOFSNOW; ++i) { SelectObject (hMemDC, GetStockObject (NULL_PEN)); Ellipse (hMemDC, snows[i].pos.x, snows[i].pos.y, snows[i].pos.x + 2*snows[i].r, snows[i].pos.y + 2*snows[i].r); } //将雪放在屏幕上 BitBlt (hScrDC, 0, 0, screen_x, screen_y, hMemDC, 0, 0, SRCCOPY); } break; case WM_LBUTTONDOWN: SendMessage (hWnd, WM_CLOSE, 0, 0); break; case WM_DESTROY: { //清理所有垃圾 ShowCursor (TRUE); KillTimer (hWnd, ID_TIME); DeleteObject (hBmp); DeleteObject (hSaveBmp); DeleteDC (hSaveDC); DeleteDC (hScrDC); InvalidateRect (NULL, NULL, TRUE); PostQuitMessage (0); } break; default: return DefWindowProc (hWnd, message, wParam, lParam); } return 0; }
栈与队列的三个例子
2010年10月05日 04:07 | Comments(31) | Category:C语言 | Tags:栈 队列 应用
1.小括号匹配
#define FORMATSTR "%c " typedef char ElemType; #define BufSize 128 #include "Stack.h" int CheckBracket(char *str, int len) { int i = 0; SQSTACK S; char ch; InitSqstack(&S, len); while(str[i]) { ch = str[i]; if(ch == '(') PushS(&S, ch); else if(ch == ')') if(!PopS(&S, &ch)) { DestroySqstack(&S); return 0; } ++i; } if(IsSqstackEmpty(S)) ; else i = 0; DestroySqstack(&S); return i; } int main(void) { //栈示例 - 括号匹配 char string[BufSize]; gets(string); if(CheckBracket(string, strlen(string))) puts("Match!"); else puts("Mismatch!"); return 0; }
2.迷宫求解
#define FORMATSTR typedef struct { int x, y, v; //坐标与方向 }ElemType; #include "Stack.h" int Map[10][10] = { 1,1,1,1,1,1,1,1,1,1, 1,0,0,1,0,0,0,1,0,1, 1,0,0,1,0,0,0,1,0,1, 1,0,0,0,0,1,1,0,0,1, 1,0,1,1,1,0,0,0,0,1, 1,0,0,0,1,0,0,0,0,1, 1,0,1,0,0,0,1,0,0,1, 1,0,1,1,1,0,1,1,0,1, 1,1,0,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,1,1,1, }; int tox[5] = {0, 0,1,0,-1}; //偏正方向 int toy[5] = {0,-1,0,1, 0}; //偏正方向 int main(void) { //链式栈示例 - 迷宫求解,给定的迷宫,输出所有解。 LINKSTACK S; ElemType e; int x, y, v; //当前坐标 int ox, oy; //修正坐标 int i, j, k = 0; e.x = 1; e.y = 1; //出发点 e.v = 0; //方向 InitLinkstack(&S); PushL(S, e); Map[1][1] = 8; while(!IsLinkstackEmpty(S)) { PopL(S, &e); x = e.x; y = e.y; v = e.v + 1; //back from here if(e.v > 0) Map[y+toy[e.v]][x+tox[e.v]] = 0; while(v <= 4) { ox = x + tox[v]; oy = y + toy[v]; if(ox == 8 && oy == 9) //终点 { printf("Answer %d:\n", ++k); for(i = 0; i < 10; ++i) { for(j = 0; j < 10; ++j) printf("%d ", Map[i][j]); putchar(10); } ++v; } else if(ox > 0 && oy > 0 && !Map[oy][ox]) { e.x = x; e.y = y; e.v = v; PushL(S, e); x = ox, y = oy; v = 1; Map[y][x] = 8; } else ++v; } } DestroyLinkstack(&S); return 0; }
3.最短路径
#define FORMATSTR typedef struct { int x, y, pre; //坐标与方向 }ElemType; #include "Queue.h" int Map[10][10] = { 1,1,1,1,1,1,1,1,1,1, 1,0,0,1,0,0,0,1,0,1, 1,0,0,1,0,0,0,1,0,1, 1,0,0,0,0,1,1,0,0,1, 1,0,1,1,1,0,0,0,0,1, 1,0,0,0,1,0,0,0,0,1, 1,0,1,0,0,0,1,0,0,1, 1,0,1,1,1,0,1,1,0,1, 1,1,0,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,1,1,1, }; int tox[5] = {0, 0,1,0,-1}; //偏正方向 int toy[5] = {0,-1,0,1, 0}; //偏正方向 int main(void) { //队列示例 - 迷宫的最短路径 SQQUEUE Q; ElemType e; int x, y, v; //当前坐标 int ox, oy; //修正坐标 int i, j, k = 0, step = 2; //从02开始 e.x = 1; e.y = 1; //出发点 e.pre = 2; //前驱 InitSqqueue(&Q, 10*10); EnSqqueue(&Q, e); Map[1][1] = step; while(!IsSqqueueEmpty(Q)) //BFS { DeSqqueue(&Q, &e); x = e.x; y = e.y; v = e.pre += 1; for(i = 1; i <= 4; ++i) { e.x = x + tox[i]; e.y = y + toy[i]; if(Map[e.y][e.x] == 0) { EnSqqueue(&Q, e); Map[e.y][e.x] = e.pre; if(e.x == 8 && e.y == 8) //终点 { printf("The Shortest Path is:\n"); for(i = 0; i < 10; ++i) { for(j = 0; j < 10; ++j) printf("%02d ", Map[i][j]); putchar(10); } DestroySqqueue(&Q); return 0; //找到就停 } } } } DestroySqqueue(&Q); return 0; }