中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

站長(zhǎng)工具國(guó)產(chǎn)搜索熱度查詢

站長(zhǎng)工具國(guó)產(chǎn),搜索熱度查詢,怎么用新浪云做淘寶客網(wǎng)站,動(dòng)態(tài)網(wǎng)站建設(shè)案例計(jì)算器 文章目錄 計(jì)算器前言簡(jiǎn)單的四則運(yùn)算UI界面事件的邏輯小結(jié) 前言 筆者應(yīng)組內(nèi)要求,簡(jiǎn)單實(shí)現(xiàn)了一個(gè)可以完成簡(jiǎn)單四則運(yùn)算的計(jì)算器程序。UI界面則是通過(guò)最近學(xué)習(xí)的Masonry庫(kù)來(lái)實(shí)現(xiàn)的,而簡(jiǎn)單的四則運(yùn)算內(nèi)容則是通過(guò)棧來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的四則運(yùn)算。 簡(jiǎn)單…

計(jì)算器

文章目錄

  • 計(jì)算器
    • 前言
    • 簡(jiǎn)單的四則運(yùn)算
    • UI界面
    • 事件的邏輯
    • 小結(jié)

前言

筆者應(yīng)組內(nèi)要求,簡(jiǎn)單實(shí)現(xiàn)了一個(gè)可以完成簡(jiǎn)單四則運(yùn)算的計(jì)算器程序。UI界面則是通過(guò)最近學(xué)習(xí)的Masonry庫(kù)來(lái)實(shí)現(xiàn)的,而簡(jiǎn)單的四則運(yùn)算內(nèi)容則是通過(guò)棧來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的四則運(yùn)算。

簡(jiǎn)單的四則運(yùn)算

筆者這里四則運(yùn)算的思路是一個(gè)中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式的方式,然后再通過(guò)后綴表達(dá)式來(lái)進(jìn)行一個(gè)計(jì)算,然后得到一個(gè)結(jié)果。這里中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式的思路主要參考這篇博客《數(shù)據(jù)結(jié)構(gòu)》:中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式 + 后綴表達(dá)式的計(jì)算

這里簡(jiǎn)單說(shuō)明一下我們?yōu)槭裁丛谟?jì)算機(jī)中要將中綴表達(dá)式轉(zhuǎn)換成后綴表達(dá)式,中綴表達(dá)式的順序是混亂的(因?yàn)橛欣ㄌ?hào)和每個(gè)符號(hào)優(yōu)先級(jí)的問(wèn)題),而轉(zhuǎn)化成后綴表達(dá)式的邏輯就會(huì)變得很簡(jiǎn)單,我們只用按照棧中的順序來(lái)進(jìn)行一個(gè)運(yùn)算就可以了。

中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式的核心思想其實(shí)就是對(duì)于我們的運(yùn)算符的順序的控制,如果遇到右括號(hào)的話,我們要一直讓符號(hào)棧一直出棧直到遇到左括號(hào)才停止。遇到操作符的話,我們只需要滿足下面這個(gè)條件就可以了,棧為空或者是我們的當(dāng)前的操作符的優(yōu)先級(jí)大于棧頂元素的操作符時(shí)候,我們的操作符棧就可以停止出棧了,然后給當(dāng)前讀到的操作符入棧。

對(duì)于數(shù)字我們都是進(jìn)行一個(gè)直接入棧。

這里給出一個(gè)C語(yǔ)言版本:

typedef struct Stack {char stk[80];int top;
}Stack;
int EmptyStack(Stack* stk) {if (stk->top == -1) {return 1;} else {return 0;}
}
char getTopStack(Stack* stk) {if (EmptyStack(stk)) {return -1;} else {return stk->stk[stk->top];}
}
int fullStack(Stack* stack) {if (stack->top == 80) {return 1;} else {return 0;}
}
void pushStack(Stack* stack, char a) {if (fullStack(stack)) {return;} else {stack->stk[++stack->top] = a;}
}
char popStack(Stack* stack) {if (EmptyStack(stack)) {return -1;} else {return stack->stk[stack->top--];}
}
int isDigit(char a) {int flag;switch (a) {case '0':flag = 1;break;case '1':flag = 1;break;case '2':flag = 1;break;case '3':flag = 1;break;case '4':flag = 1;break;case '5':flag = 1;break;case '6':flag = 1;break;case '7':flag = 1;break;case '8':flag = 1;break;case '9':flag = 1;break;default:flag = 0;break;}return flag;
}
char** changeStack(Stack* stk, int length, char* s, int* num1) {char** string = (char**)malloc(sizeof(char*) * 30);for (int i = 0; i < 30; i++) {string[i] = (char*)malloc(sizeof(char) * 10);}int num = 0;int tail = 0;for (int i = 0; i < length; i++) {if (s[i] == '(') {pushStack(stk, s[i]);} else if (s[i] == ')') {if (tail > 0) {string[num][tail] = '\0';num++;tail = 0;}while (!EmptyStack(stk) && getTopStack(stk) != '(') {string[num][0] = popStack(stk);string[num][1] = '\0';num++;}popStack(stk);} else if (isDigit(s[i]) || s[i] == '.') {string[num][tail++] = s[i];} else if (s[i] == '+' || s[i] == '-') {if (i == 0 || (i > 0 && !isDigit(s[i - 1]) && s[i - 1] != ')' && s[i] == '-')) {string[num][tail++] = s[i];} else {if (tail > 0) {string[num][tail] = '\0';num++;tail = 0;}while (!EmptyStack(stk) && (getTopStack(stk) == '*' || getTopStack(stk) == '/' || getTopStack(stk) == '+' || getTopStack(stk) == '-')) {string[num][0] = popStack(stk);string[num][1] = '\0';num++;}pushStack(stk, s[i]);}} else if (s[i] == '*' || s[i] == '/') {if (tail > 0) {string[num][tail] = '\0';num++;tail = 0;}while (!EmptyStack(stk) && (getTopStack(stk) == '*' || getTopStack(stk) == '/')) {string[num][0] = popStack(stk);string[num][1] = '\0';num++;}pushStack(stk, s[i]);}}if (tail > 0) {string[num][tail] = '\0';num++;}while (!EmptyStack(stk)) {string[num][0] = popStack(stk);string[num][1] = '\0';num++;}*num1 = num;return string;
}
int isNumber(char* token) {return strlen(token) > 1 || ('0' <= token[0] && token[0] <= '9');
}
double change(char* token) {double x = 0;double decimalFactor = 1.0;int index = -1;int flag = 1;if (token[0] == '-') {flag = -1;}for (int i = 0; i < strlen(token); i++) {if (token[i] == '-') {continue;}if (token[i] == '.') {index = i;} else {if (index == -1) {x = x * 10 + (token[i] - '0');} else {decimalFactor *= 0.1;x += (token[i] - '0') * decimalFactor;}}}printf("%lf\n", x * flag);return x * flag;
}
double evalRPN(char** tokens, int tokensSize) {int n = tokensSize;double stk[n];int top = 0;for (int i = 0; i < n; i++) {char* token = tokens[i];if (strlen(token) == 0) {continue;}if (isNumber(token)) {stk[top++] = change(token);} else {double num2 = stk[--top];double num1 = stk[--top];switch (token[0]) {case '+':stk[top++] = num1 + num2;break;case '-':stk[top++] = num1 - num2;break;case '*':stk[top++] = num1 * num2;break;case '/':stk[top++] = num1 / num2;break;}}}return stk[top - 1];
}

這里和上面簡(jiǎn)單的版本有一點(diǎn)區(qū)別,這里的還考慮到了一個(gè)負(fù)數(shù)的判別和一個(gè)小數(shù)點(diǎn)的時(shí)候?qū)τ谖覀兊臄?shù)字的一個(gè)讀取特別判斷,這里如果是數(shù)字或者是一個(gè)小數(shù)點(diǎn)我們都要繼續(xù)進(jìn)行一個(gè)讀取。這里我對(duì)于負(fù)數(shù)的處理是將負(fù)號(hào)存儲(chǔ)到我們對(duì)應(yīng)的數(shù)字前面,因?yàn)橐粋€(gè)數(shù)字如果是負(fù)數(shù)的話,那他的負(fù)號(hào)是鏈接在運(yùn)算符后面的,或者鏈接在左括號(hào)后面的。所以通過(guò)一個(gè)特判,來(lái)分辨我們的普通符號(hào)減和一個(gè)負(fù)數(shù)的標(biāo)志。

但是在OC中給出了一個(gè)類NSDecimalNumber這個(gè)類可以實(shí)現(xiàn)一個(gè)比較精確的加減乘除,下面給出我們使用這個(gè)類來(lái)實(shí)現(xiàn)計(jì)算的過(guò)程

- (NSDecimalNumber*) evalRPN {NSInteger n = self.ary.count;NSLog(@"%@", self.ary);NSMutableArray* stack = [NSMutableArray array];//int top = 0;for (int i = 0; i < n; i++) {NSString* token = self.ary[i];if (token.length == 0) {continue;}if ([self isNumber:token]) {[stack addObject: [self change:token]];} else {NSDecimalNumber* num2 = [stack lastObject];[stack removeLastObject];NSDecimalNumber* num1 = [stack lastObject];[stack removeLastObject];if ([token isEqualToString:@"+"]) {[stack addObject:[num1 decimalNumberByAdding:num2]];} else if ([token isEqualToString:@"-"]) {[stack addObject:[num1 decimalNumberBySubtracting:num2]];} else if ([token isEqualToString:@"×"]) {[stack addObject:[num1 decimalNumberByMultiplyingBy:num2]];} else if ([token isEqualToString:@"÷"]) {[stack addObject:[num1 decimalNumberByDividingBy:num2]];}}}if (stack.count > 1) {return nil;} else {return [stack lastObject];}
}

UI界面

在這里插入圖片描述

UI界面采用了Masonry來(lái)布局,這個(gè)界面大致有兩個(gè)部分組成一個(gè)是我們的textField,剩下的部分則是我們的按鈕部分,這里布局我采用了一個(gè)for循環(huán)來(lái)不斷創(chuàng)建我們的button,并且給這些button賦值對(duì)應(yīng)的tag,這樣方便我們對(duì)于具有不同button的進(jìn)行一個(gè)劃分。

UIView* preView = nil;
for (int i = 0; i < 19; i++) {UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect];[self addSubview:button];//button.backgroundColor = UIColor.whiteColor;[button setTitle:ary[i] forState:UIControlStateNormal];[button setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];button.titleLabel.font = [UIFont systemFontOfSize:37];button.tag = 100 + i;if (i == 0) {[button mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(self).offset(20);make.top.equalTo(self.textField.mas_bottom).offset(10);make.size.equalTo(@80);}];} else if (i % 4 == 0 && i != 16) {[button mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(self).offset(20);make.top.equalTo(preView.mas_bottom).offset(10);make.size.equalTo(@80);}];} else if (i == 16) {[button mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(self).offset(20);make.top.equalTo(preView.mas_bottom).offset(10);make.width.equalTo(@170);make.height.equalTo(@80);}];} else {[button mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(preView.mas_right).offset(10);make.top.equalTo(preView);make.size.equalTo(@80);}];}button.layer.cornerRadius = 80 / 2;button.layer.masksToBounds = YES;preView = button;}for (UIView* subview in self.subviews) {if ([subview isKindOfClass:[UIButton class]]) {if (subview.tag < 103) {subview.backgroundColor = UIColor.lightGrayColor;} else if (subview.tag == 103 || subview.tag == 107 || subview.tag == 111 || subview.tag == 115 || subview.tag == 118) {subview.backgroundColor = UIColor.orangeColor;} else {subview.backgroundColor = UIColor.darkGrayColor;}}}

這部分代碼是一個(gè)創(chuàng)建button的代碼,然后根據(jù)button的不同tag來(lái)分配顏色以及設(shè)置對(duì)應(yīng)的位置。

因?yàn)椴捎肕VC架構(gòu),所以我這里將所有給button添加事件的函數(shù)都放在了ViewController中。

 for (UIView* subview in _myView.subviews) {if ([subview isKindOfClass:[UIButton class]]) {UIButton* myButton = (UIButton*)subview;if (subview.tag == 100) {[myButton addTarget:self action:@selector(empty) forControlEvents:UIControlEventTouchUpInside];} else if (subview.tag == 103 || subview.tag == 102 || subview.tag == 101 || subview.tag == 107 || subview.tag == 111 || subview.tag == 115 || subview.tag == 117) {[myButton addTarget:self action:@selector(pressopator:) forControlEvents:UIControlEventTouchUpInside];} else if (subview.tag == 118) {[myButton addTarget:self action:@selector(pressEqual:)forControlEvents:UIControlEventTouchUpInside];NSLog(@"12");} else {[myButton addTarget:self action:@selector(pressNum:) forControlEvents:UIControlEventTouchUpInside];}}}

這部分實(shí)現(xiàn)了一個(gè)給button添加事件函數(shù)。

這里可以注意一下textfieldadjustsFontSizeToFitWidth屬性可以讓他根據(jù)字符串長(zhǎng)度來(lái)實(shí)現(xiàn)一個(gè)自適應(yīng)字體的效果。

在這里插入圖片描述

事件的邏輯

這里筆者對(duì)于輸入運(yùn)算符做了限制,同時(shí)也對(duì)我們輸入的小數(shù)點(diǎn)和左右括號(hào)都做了限制。

比方說(shuō)筆者在一開(kāi)始只允許我們的負(fù)號(hào)輸入和左括號(hào)允許輸入,別的操作符被設(shè)置成無(wú)法鍵入符號(hào)的狀態(tài)。

又或者是在輸入數(shù)字的時(shí)候限制他只能輸入一個(gè)小數(shù)點(diǎn)。

這部分的邏輯其實(shí)比較復(fù)雜,要考慮的內(nèi)容也比較多。比方說(shuō)判斷數(shù)字的小數(shù)點(diǎn)個(gè)數(shù)是否符合要求或者是判斷多個(gè)運(yùn)算符重疊的情況。

在這里插入圖片描述

這里我主要把這部分的判斷分成了兩部分,一個(gè)是通過(guò)一些全局變量來(lái)控制一些不合理的輸入,另一個(gè)則是通過(guò)判斷中綴表達(dá)式是否合理來(lái)然后返回一個(gè)error字符串。

這里我是通過(guò)一個(gè)dotFlag和numFlag來(lái)控制他一個(gè)數(shù)字只能輸入一次小數(shù)點(diǎn),從而限制輸入。另一個(gè)部分就是我們開(kāi)始我設(shè)置成只可以輸入的符號(hào)只有負(fù)號(hào)。

小結(jié)

計(jì)算器的仿寫(xiě)比較困難的點(diǎn)在于我們需要考慮的問(wèn)題比較多,以及對(duì)于字符串的處理需要注意一下。細(xì)節(jié)地方比較多。

http://www.risenshineclean.com/news/12216.html

相關(guān)文章:

  • 金昌市建設(shè)局網(wǎng)站外鏈服務(wù)
  • 滕州手機(jī)網(wǎng)站建設(shè)案例google關(guān)鍵詞排名
  • 北京海淀區(qū)疫情最新情況解釋seo網(wǎng)站推廣
  • 革命幻燈片 wordpress365優(yōu)化大師軟件下載
  • 遵義網(wǎng)站推廣百度新聞下載安裝
  • 電子商務(wù)網(wǎng)站設(shè)計(jì)分析怎么做大量微信群推廣代發(fā)廣告
  • 濰坊做電商的網(wǎng)站建設(shè)品牌營(yíng)銷推廣要怎么做
  • b2b網(wǎng)站模塊重慶seo整站優(yōu)化效果
  • 廣州市建設(shè)局官方網(wǎng)站代運(yùn)營(yíng)哪家公司最靠譜
  • 高端網(wǎng)站建設(shè) 磐石網(wǎng)絡(luò)專注徐州seo排名公司
  • 為網(wǎng)站做seo需要什么軟件百度做推廣一般要多少錢(qián)
  • 來(lái)年做那些網(wǎng)站致富人工智能培訓(xùn)班收費(fèi)標(biāo)準(zhǔn)
  • 合肥做公司網(wǎng)站一般多少錢(qián)蘇州百度推廣排名優(yōu)化
  • 新的網(wǎng)站設(shè)計(jì)公司宜昌今日頭條新聞
  • 手機(jī)網(wǎng)站開(kāi)發(fā)書(shū)籍百度搜索引擎首頁(yè)
  • 旅游網(wǎng)站排名查詢百度推廣投訴中心
  • 做網(wǎng)站需要公司授權(quán)嘛成都最新熱門(mén)事件
  • wordpress 排版代碼seo技術(shù)優(yōu)化服務(wù)
  • 機(jī)票網(wǎng)站開(kāi)發(fā)百度網(wǎng)址大全官方網(wǎng)站
  • 俄語(yǔ)學(xué)習(xí)網(wǎng)站下載谷歌瀏覽器
  • 做企業(yè)網(wǎng)站需要買(mǎi)什么百度有幾個(gè)總部
  • 短視頻培訓(xùn)機(jī)構(gòu)seo入門(mén)到精通
  • 網(wǎng)站上文章字體部分復(fù)制怎么做seo關(guān)鍵詞排名優(yōu)化怎么樣
  • 武安市網(wǎng)站建設(shè)青島運(yùn)營(yíng)網(wǎng)絡(luò)推廣業(yè)務(wù)
  • 營(yíng)銷培訓(xùn)班深圳短視頻seo教程
  • 360搜索建站公司免費(fèi)發(fā)布推廣的網(wǎng)站有哪些
  • 墻蛙網(wǎng)站誰(shuí)家做的搜索引擎優(yōu)化概述
  • 網(wǎng)站懸浮廣告代碼網(wǎng)站策劃書(shū)模板范文
  • 自己做網(wǎng)站教程做銷售有什么技巧和方法
  • 個(gè)人網(wǎng)站主頁(yè)設(shè)計(jì)網(wǎng)絡(luò)優(yōu)化的基本方法