3.你所不知道的go語言控制語句——Leetcode習題69

来源:https://www.cnblogs.com/onlyac/archive/2023/08/20/17643470.html
-Advertisement-
Play Games

[TOC] # 本篇前瞻 好的,現在你已經來到一個新的小結,在這裡你將學習到go語言的重要內容,習得go 25個關鍵字中的12個:var, const, if, else, switch, case, default, fallthrough, for, break, goto, continue, ...


目錄

本篇前瞻

好的,現在你已經來到一個新的小結,在這裡你將學習到go語言的重要內容,習得go 25個關鍵字中的12個:var, const, if, else, switch, case, default, fallthrough, for, break, goto, continue,即在順序結構學習var,const,在分支結構中學習if, else, switch, case, default, fallthrough,在迴圈結構中學習for, break, goto, continue。另外你最好註冊一個Leetcode賬號.

Leetcode習題9

讓我們再來看下這個例子,這個是一個比較好的例子,裡面包含了順序,分支以及迴圈的所有控制結構

題目描述

9. 迴文數

給你一個整數 x ,如果 x 是一個迴文整數,返回 true ;否則,返回 false

迴文數是指正序(從左向右)和倒序(從右向左)讀都是一樣的整數。

代碼編寫

func isPalindrome(x int) bool {
	if (x < 0) { //分支結構
		return false
	}
	x64 := x   //順序結構
	px64 := 0
	for x64 != 0 {  //迴圈結構
		px64 = px64*10 + x64%10 // 順序結構
		x64 /= 10
	}
	return px64 == x 
}

你在這個道題目中能看到所有的控制結構:順序結構,分支結構,迴圈機構

控制結構

順序結構(Sequence)

聲明和賦值

在順序結構中聲明和賦值是很重要的

var可以聲明一個變數,而const則聲明一個常量

package main

import "fmt"

func main() {
	var i1 int     //聲明變數,預設值為0
	var i2 int = 1 //聲明變數,初始化為1
	i3 := 2        //這是最常用的聲明和初始化手段
	fmt.Println(i1, i2, i3)
	i4 := i2 + i3 //使用運算表達式賦值
	i3 *= i4      //使用運算表達式賦值
	fmt.Println(i3, i4)
	const ci1 int = 13 //聲明常量,無法
	fmt.Println(ci1)
	x, y, z := 100, 101, 102 //多返回值
	fmt.Println(x, y, z)     //列印結果
}

輸出:

0 1 2
6 3
13
100 101 102

這裡僅僅舉例了整形int的聲明

多返回值賦值

x,y,z := 0,1,2

go語言允許這樣多返回值賦值賦值方式,再挖個坑,原因會在介紹函數時說明一下。

運算符

算術運算符

++ --
自增1 自減1
+= -= *= /= %=
自增 自減 自乘 自除 自模,取餘
+ - * / %
加法 減法 乘法 除法 模,取餘

註意: 例如如3/2 在整型中是整除即3/2=1,在浮點型是3.0/2.0=1.5,模運算智能用於整數

位運算符

<< >> & | ^
左移 右移 亦或
<<= >>= &= |= ^=
自左移 自右移 自與 自或 自亦或

位運算符幾乎我們這篇實用的編程用不到,但是這個概念也很重要,電腦底層事實上是這樣工作的,這裡在挖個坑,後面會介紹位運算的相關leetcode題目,你會看到它的威力。

邏輯運算

&& || == !=
相等 不等於
>= <= > <
大於等於 小於等於 大於 小於

這些會在分支語句中大放異彩。

分支結構

if 語句

if 語句有if,if-else以及if-else if-else結構,如下所示:

package main

import "fmt"

func main() {
	var input int
	fmt.Printf("請輸入分數:")
	fmt.Scanf("%d", &input)
	if input < 60 { //if
		fmt.Println("1.不合格")
	}

	if input < 60 { //if-else
		fmt.Println("2.不合格")
	} else{
		fmt.Println("2.合格")
	}

	if input < 60 {//if-else if-else
		fmt.Println("3.不合格")
	} else if input < 70 {
		fmt.Println("3.合格")
	} else if input < 85 {
		fmt.Println("3.良好")
	} else  {
		fmt.Println("3.優秀")
	}
}

結果如下:

請輸入分數:59
1.不合格
2.不合格
3.不合格

switch 語句

事實上switch 語句比if語句更為強大,在有多個分支時更為符合go語言的風格,完整代碼如下:

package main

import "fmt"

func main() {
	var i int
	fmt.Printf("請輸入分數:")
	fmt.Scanf("%d\n", &i)
	switch {
	case i < 60: //單個邏輯表達式
		fmt.Println("不合格")
	case i < 70:
		fmt.Println("合格")
	case i < 85:
		fmt.Println("良好")
	default:
		fmt.Println("優秀")
	}

	var c byte
	fmt.Printf("請輸入等級:")
	fmt.Scanf("%c\n", &c)

	switch c {
	case 'E', 'e': //可以有多個選擇
		fmt.Println("1.不合格")
	case 'D', 'd':
		fmt.Println("1.基本合格")
	case 'C', 'c':
		fmt.Println("1.合格")
	case 'B', 'b':
		fmt.Println("1.良好")
	case 'A', 'a':
		fmt.Println("1.優秀")
	default:
		fmt.Println("1.錯誤的輸入")
	}

	switch {
	case c == 'E', c == 'e': //可以有多個表達式
		fmt.Println("2.不合格")
	case c == 'D', c == 'd':
		fmt.Println("2.基本合格")
	case c == 'C', c == 'c':
		fmt.Println("2.合格")
	case c == 'B', c == 'b':
		fmt.Println("2.良好")
	case c == 'A', c == 'a':
		fmt.Println("2.優秀")
	default:
		fmt.Println("2.錯誤的輸入")
	}

	switch {
	case c == 'E':
		fmt.Println("3.不合格")
		fallthrough //fallthrough會執行下一個case區塊
	case c == 'e':
		fmt.Println("3.真的不合格")
	case c == 'D', c == 'd':
		fmt.Println("3.基本合格")
	case c == 'C', c == 'c':
		fmt.Println("3.合格")
	case c == 'B', c == 'b':
		fmt.Println("3.良好")
	case c == 'A', c == 'a':
		fmt.Println("3.優秀")
	default:
		fmt.Println("3.錯誤的輸入")
	}

	var in interface{} = i
	switch data := in.(type) { //類型推斷
	case int:
		fmt.Printf("int: %v\n", data)
	case uint:
		fmt.Printf("uint: %v\n", data)
	default:
		fmt.Printf("type: %T\n", data)
	}
}

結果如下:

請輸入分數:90
優秀
請輸入等級:E
1.不合格
2.不合格
3.不合格
3.真的不合格
int: 90

邏輯表達式

註意case可以是單個或多個邏輯表達式

	switch {
	case c == 'E', c == 'e': //可以有多個表達式
		fmt.Println("2.不合格")。
	case c == 'D', c == 'd':
		fmt.Println("2.基本合格")
	case c == 'C', c == 'c':
		fmt.Println("2.合格")
	case c == 'B', c == 'b':
		fmt.Println("2.良好")
	case c == 'A', c == 'a':
		fmt.Println("2.優秀")
	default:
		fmt.Println("2.錯誤的輸入")
	}

fallthrough

fallthrough會執行下一個case區塊

	switch {
	case c == 'E':
		fmt.Println("3.不合格")
		fallthrough //fallthrough會執行下一個case區塊
	case c == 'e':
		fmt.Println("3.真的不合格")
	case c == 'D', c == 'd':
		fmt.Println("3.基本合格")
	case c == 'C', c == 'c':
		fmt.Println("3.合格")
	case c == 'B', c == 'b':
		fmt.Println("3.良好")
	case c == 'A', c == 'a':
		fmt.Println("3.優秀")
	default:
		fmt.Println("3.錯誤的輸入")
	}

類型推斷

這個是一個強大的方式,它可以用於推斷go語言的介面的類型,不過現在只能簡單那介紹一下,你可以將interface{}可以表達任何類型

	var in interface{} = i
	switch data := in.(type) { //類型推斷
	case int:
		fmt.Printf("int: %v\n", data)
	case uint:
		fmt.Printf("uint: %v\n", data)
	default:
		fmt.Printf("type: %T\n", data)
	}

迴圈語句

迴圈語句只有for

package main

import "fmt"

func main() {
	var input int
	fmt.Printf("請輸入分數(0-5):")
	fmt.Scanf("%d", &input)

	for i := 0; i < 5; i++ { //正常的for
		fmt.Println("loop1:", i)

		if i < 2 {
			continue //跳過本次執行
		}
		if i == input {
			fmt.Println("loop1: break") //跳出本層迴圈
			break
		}
	}
	i := 0
Loop:
	for i < 5 { //去掉;的for迴圈
		fmt.Println("loop2:", i)
		for j := 0; j < 5; j++ {
			if j == input {
				fmt.Println("loop2: break Loop") //跳出Loop標記的迴圈
				break Loop
			}
			if j == 1 {
				break //跳出本層迴圈
			}
		}
		i++
	}
	i = 0
	for ; i < 5; i++ { //空缺一個元素並帶有;的for迴圈
		fmt.Println("loop3:", i)
		for j := 0; j < 5; j++ {
			if j < 2 {
				continue
			}
			if j == input {
				goto Exit //跳出到Exit
			}
		}
	}
	return
Exit:
	fmt.Println("loop3: Exit")
}

結果如下:

請輸入分數(0-5):1
loop1: 0
loop1: 1
loop1: 2
loop1: 3
loop1: 4
loop2: 0
loop2: break Loop
loop3: 0
loop3: 1
loop3: 2
loop3: 3
loop3: 4

請輸入分數(0-5):2
loop1: 0
loop1: 1
loop1: 2
loop1: break
loop2: 0
loop2: 1
loop2: 2
loop2: 3
loop2: 4
loop3: 0
loop3: Exit

continue

跳過本次迴圈

break

沒有加標簽的就是跳過本層迴圈

加標簽的就是跳過被標簽標記的迴圈

goto

跳到被標簽標記的迴圈,使用goto在處理一些同意的錯誤或者統一的出口而降低代碼的冗餘,增加代碼可讀性。這裡挖個坑,這裡會在go-etl展示goto的魅力

註意:很多書籍指出goto會破環代碼結構,降低代碼可讀性,那是因為這些書籍講述使用goto的場景錯了

Leetcode習題69

我們以leetcode習題開始,而現在有以一道Leetcode習題結束

題目描述

69. x 的平方根

給你一個非負整數 x ,計算並返回 x算術平方根

由於返回類型是整數,結果只保留 整數部分 ,小數部分將被 捨去 。

註意:不允許使用任何內置指數函數和算符,例如 pow(x, 0.5) 或者 x ** 0.5

題目分析

這道題會比Leetcode習題1更加困難些,這次數據範圍是int32的非負整數範圍,由於不能使用指數函數和算符,為此,在這裡我們需要使用二分法,即通過二分[a,b](mid = a + (b-a)/2, 第一輪a=0,b=x)去獲取mid=x/2,如果mid*mid<x 那麼此時二分[a,mid-1],反之二分[mid+1,b], 這樣不斷二分下去直到 mid*mid=x或者a<b。好的,這樣我們獲得瞭解題思路,但是還有個問題,選擇y的數據類型是什麼,如果選擇int32,那麼相乘必然超過int32, 為此我們必須選擇int64,註意:在Leetcode習題9中得出了結論,int是64位的,所以不用改為int64

代碼編寫

func mySqrt(x int) int {
	a, b := 0, x //多返回值賦值
	for a <= b { // 無;結構的for
		mid := a + (b-a)/2   //二分區間
		if mid*mid == x { //if語句
			return mid
		}
		if mid*mid < x { //if-else語句
			a = mid + 1   //選擇較大的區間
		} else {
			b = mid - 1  //選擇較小的區間
		}
	}
	return b
}

本篇小結

恭喜你已經完成了所有控制結構的學習,你以及知道了所有控制結構用到的保留字和註意點。另外,通過Leetcode習題69和Leetcode習題9,你已經知道在編程時選擇數據類型的重要性,並且練習了所有控制結構。這裡的相關代碼放在go語言學習的go-base/3中,請下載後進行實際的練習

註意:之後的Leetcode題目解答以及使用工具的編程中,數據類型的選擇以及控制結構的應用是非常重要的,也是最為基礎的

下篇預告

go語言複合類型


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文旨在根據LOVE2D官方文檔和教程實現打磚塊的游戲,記錄部分實現過程和重要知識點 - 目標摧毀所有磚塊 - 玩家控制球拍左右滑動反彈小球 - 小球摧毀磚塊 - 小球保持在屏幕內 - 小球碰到屏幕底部,GAME OVER ## 引擎配置 ```lua -- conf.lua love.conf = ...
  • ## 前提 之前曾經寫過一篇[《SpringBoot3.x 原生鏡像-Native Image 嘗鮮》](https://vlts.cn/post/spring-boot-native-image-demo),當時`SpringBoot`處於`3.0.0-M5`版本,功能尚未穩定。這次會基於`Spr ...
  • ### POM.XML配置 ``` 4.0.0 com.shouke des-utils 1.0 1.8 ${java.version} ${java.version} UTF-8 UTF-8 cn.hutool hutool-all 4.1.0 ``` ## 代碼實現 ```groovy pack ...
  • # 網路編程 ## 一、概述 網路編程是指編寫運行在多個設備(電腦)的程式,這些設備都通過網路連接起來。 ### 電腦網路 把分佈在不同地理區域的電腦與專門的外部設備用通信線路互連成一個規模大,功能強的網路系統, 從而使眾多的電腦可以方便地互相傳遞信息,共用硬體,軟體,數據信息等資源。 ## ...
  • 在Python中,元組(Tuple)是一種有序且不可變的數據類型。元組可以包含任意數量的元素,用逗號分隔,並用圓括弧括起來。與列表(List)不同,元組的元素不能修改。元組與列表一樣,可以通過索引訪問其中的元素。 ```python my_tuple = ("apple", "banana", "c ...
  • OpenAI的Karpathy利用周末搞了一個迷你Llama2項目llama2.c用500行C語言實現無任何依賴項的推理程式,此項目在github發佈以來衍生出了基於各種語言的迷你Llama推理實現llama2.go、llama2.java、llama2.py等等; 但該項目原本的模型並不支持中文, ...
  • # wangyi > 記錄一次某大廠筆試的AC過程 ![image-20230820152914557](https://img2023.cnblogs.com/blog/2862884/202308/2862884-20230820160050687-208549606.png) ``給定一個二維 ...
  • ## 一,下載安裝相關 ### 1,這個軟體什麼作用? Anaconda:Python大禮包(包含解析器,一系列庫,軟體包管理器Conda) 主要作用,不用配庫,如果需要庫a,anaconda會把庫a相關的依賴庫一併打包下載 次要作用,可以同時安裝不同版本的python,和對應依賴庫,相互隔離。 # ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...