瀏覽標籤:

C#

[C#][LeetCode] 28. Implement strStr()

從傳入參數 haystack 中找出參數 needle 中的索引位置,非常基礎的一題

我的答案

public class Solution {
    public int StrStr(string haystack, string needle) {
        if(needle == null || needle == string.Empty){
            return 0;
        } else if(haystack == null){
            return -1;
        }
        
        return haystack.IndexOf(needle);
    }
}

 

       

[C#][LeetCode] 2. Add Two Numbers

輸入兩個 ListNode 物件並將兩個相同層數的數值加總,其值若超過 10 需進位到下個節點,這題我覺得迴圈解法比遞迴更讓人腦袋卡住,可能是我功力不夠吧。

我的遞迴解答:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode AddTwoNumbers(ListNode l1, ListNode l2) {
        return Add(l1, l2, 0);
    }
    
    public ListNode Add(ListNode l1, ListNode l2, int addNum = 0)
    {
        if(l1 == null && l2 == null)
        {
            return null;                 
        }
        
        l1 = l1 ?? new ListNode(0);
        l2 = l2 ?? new ListNode(0);
        
        int i = (l1.val + l2.val) + addNum;
        ListNode totalNode = new ListNode(i % 10);
        if(l1.next != null || l2.next != null)
        {
            totalNode.next = Add(l1.next, l2.next, (i / 10));
        }
        
        if(i >= 10 && totalNode.next == null)
        {
            totalNode.next = new ListNode(1);
        }
             
        return totalNode;
    }
}

 

 

我的迴圈作法:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public int val;
 *     public ListNode next;
 *     public ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode AddTwoNumbers(ListNode l1, ListNode l2) {
        
        int sumValue = 0;
        int carryValue = 0;
        
        ListNode ansNode = new ListNode(-1);
        
        // 將 ansNode 的記憶體位置指向給 node
        ListNode node = ansNode;
        
        while(l1 != null || l2 != null)
        {
            sumValue = carryValue;
            
            if(l1 != null)
            {
                sumValue += l1.val;
                l1 = l1.next;
            }
            
            if(l2 != null)
            {
                sumValue += l2.val;
                l2 = l2.next;
            }
            
            carryValue = (sumValue / 10);
            if(carryValue > 0)
            {
                sumValue = (sumValue % 10);
                
                // 若大於 10 且 l1 與 l2 都沒有下個節點,那就自己創造一個
                if(l1 == null && l2 == null)
                {
                    l1 = new ListNode(0);
                }
            }
                        
            if(ansNode.val == -1)
            {
                ansNode.val = sumValue;
            }
            else
            {                
                node.next = new ListNode(sumValue);
                
                // 將當前物件 node.next 的記憶體位置指向到 node,這樣就可以達到一層一層改變 ansNode.next 值的效果
                node = node.next;
            }
        }
        
        return ansNode;
    }

    
}

 

 

       

[C#][LeetCode] 804. Unique Morse Code Words

這題要將英文轉換成摩斯密碼,並計算出重複字串的數量,我用 Linq 輕鬆解決。

public class Solution {
    
    public int UniqueMorseRepresentations(string[] words) {
        
        string[] morseCode = new string[] {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
        
        List<char> listAToZ = Enumerable.Range('a', 26)
                                        .Select(x => (char)x)
                                        .ToList();
        
        var morseCodeAns = words.Select(x => 
        {
            var temp = x.Select(y => morseCode[listAToZ.IndexOf(y)]);            
            return string.Join(string.Empty, temp);
        });
        
        return morseCodeAns.Distinct().Count();
    }
}

 

       

[C#][LeetCode] 8. String to Integer (atoi)

外部輸入一個字串,若開頭為數字的話或 +- 符號的話則轉換為 int 的型態,且若超過 int 的最大或最小值則取極限值為準。

我的第一版答案如下:

public class Solution {
    public int MyAtoi(string str) {
        var arrNum = "0123456789".ToList();
        var arrSymbol = "-".ToList();

        if (string.IsNullOrWhiteSpace(str))
        {
            return 0;
        }
        else
        {
            str = str.Trim();
        }

        bool isFirstAddSymbol = (str[0] == '+');

        if (isFirstAddSymbol)
        {
            str = str.Substring(1);
        }

        if (string.IsNullOrWhiteSpace(str))
        {
            return 0;
        }

        bool isFirstNum = (arrNum.IndexOf(str[0]) != -1);
        bool isFirstSymbol = (arrSymbol.IndexOf(str[0]) != -1);

        if ((isFirstAddSymbol && isFirstSymbol) ||
            (!isFirstNum && !isFirstSymbol) ||
            (isFirstSymbol && str.All(x => arrNum.IndexOf(x) == -1)) ||
            (isFirstSymbol && str.Length > 1 && (arrNum.IndexOf(str[1]) == -1)))
        {
            return 0;
        }

        string numString = string.Empty;
        str = isFirstSymbol ? str.Substring(1) : str;

        for (int i = 0; i < str.Length; i++)
        {

            bool isNum = (arrNum.IndexOf(str[i]) != -1);

            if (!isNum)
            {
                break;
            }

            if (numString == "0")
            {
                numString = str[i].ToString();
            }
            else
            {
                numString += str[i].ToString();
            }

        }

        int maxValueLength = int.MaxValue.ToString().Length;
        long ans = int.MaxValue;

        bool isMoreMax = (numString.Length > maxValueLength) || (long.Parse(numString) > int.MaxValue);

        if (!isMoreMax)
        {
            ans = long.Parse(numString);
        }

        if (isFirstSymbol && isMoreMax)
        {
            ans += 1;
        }

        return Convert.ToInt32(isFirstSymbol ? -ans : ans);
    }
}

 

 

參考最佳解答後的優化版:

public class Solution {
    public int MyAtoi(string str) {
        str = (str ?? string.Empty).Trim();
        
        if (string.IsNullOrWhiteSpace(str))
        {
            return 0;
        }
        
        bool isMinusSign = (str[0] == '-');
        if (isMinusSign || (str[0] == '+'))
        {
            
            if ((str.Length == 1) ||
                ((str.Length > 1) && (str[1] < '0' || str[1] > '9')))
            {
                return 0;
            }
            
            str = str.Substring(1);
        }
        
        string numString = string.Empty;
        foreach (var item in str)
        {
            bool isNum = (item >= '0' && item <= '9');
            
            if (!isNum) {
                break;
            }
            
            if (numString == "0")
            {
                numString = item.ToString();
            }
            else
            {
                numString += item.ToString();
            }
        }
        
        if (numString == string.Empty)
        {
            return 0;
        }

        int maxValueLength = int.MaxValue.ToString().Length;
        long ans = int.MaxValue;

        bool isMoreMax = (numString.Length > maxValueLength) || (long.Parse(numString) > int.MaxValue);

        if (!isMoreMax)
        {
            ans = long.Parse(numString);
        }

        if (isMinusSign && isMoreMax)
        {
            ans += 1;
        }

        return Convert.ToInt32(isMinusSign ? -ans : ans);
    }
}

 

       

[.NET Core] EFCore Generate DbModel

使用 EFCore 的時候沒有看有地方可以像 .NET Framework 可以直接使用 VS 新增 edmx 產生好資料庫的 Model 與 DbContext,這個時候就必須靠自己拉,不過當 Table 多的時候這樣人工慢慢新增 Model 有點智障,於是乎就上網找到了 EFCore Tool 有提供一段命令可以使用。

網址:https://docs.microsoft.com/zh-tw/ef/core/miscellaneous/cli/powershell

這裡就來簡單做個筆記

  1. 首先在 Package Manager Console 輸入指令安裝 EFCore Tool
Install-Package Microsoft.EntityFrameworkCore.Tools
  1. 若為 Win7 需要先裝 Windows Management Framework 3.0 否則會跟我一樣出現下面的錯誤
    錯誤畫面

  2. 檔案可以在 這裡 找到下載安裝並重開機。

  3. 產生 Model 前需注意一件事情就是密碼不能有 $ 符號,不然會跟我一樣鬼打牆一小時都找不到問題,我有嘗試使用單引號包起來,但依然無法成功連線

  4. 接著在 Package Manager Console 輸入指令 (適用於 Azure SQL DataBase)

Scaffold-DbContext "Server={ip};Initial Catalog={dbName};Persist Security Info=False;User ID={Account};Password={Password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir {Path}
  1. 接著就可以看到 VS 裡面跑出 DbModel 與 DbContext 囉 !!
       

[C#][Visual Studio 2017] 修改預設 class 存取範圍成 public

版本:Visual Studio 2017 Enterprise

路徑:

C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\ItemTemplates\CSharp\Code\1028\Class\Class.cs

 

範本:

using System;
using System.Collections.Generic;
$if$ ($targetframeworkversion$ >= 3.5)using System.Linq;
$endif$using System.Text;
$if$ ($targetframeworkversion$ >= 4.5)using System.Threading.Tasks;
$endif$
namespace $rootnamespace$
{
    public class $safeitemrootname$
    {
    }
}

 

這樣就新增 class 時就會自己加上 public 囉

       

[SideProject] Gif 產生器

動機

原作者是 ruby 寫的 sorry

感覺頗有趣的就寫個 .NET 版來玩玩了

由於很懶所以沒有優化歡迎PR

專案說明

本專案是用 Visual Studio 2017 開發

基本上只要裝了微軟爸爸的 VS 後直接 F5 就可以執行了

若有問題歡迎發 Issues

連結

GitHub:https://github.com/shuangrain/SorryNet

Blog:https://blog.exfast.me/2018/03/side-project-gif-generator/

Demo:https://exfast-sorry.azurewebsites.net/

       

[SideProject] 財政部電子發票 API 測試工具

財政部電子發票 API 測試工具

這是我最近在串接財政部 API 時自己寫的測試工具,希望能讓大家在串接測試上更加方便。
歡迎 PR 財政部的 API 清單

操作說明

  • 環境變數
  1. 簽章 (Signature):將 Request 參數按照名稱排序並以 HMAC-SHA1 加密後加在 Query 後方傳送至財政部
  2. 測試環境:將資料傳送至財政部測試環境
  3. Client 模式:以另開新頁的方式呼叫財政部 API
  • 選擇 Api
    要測試的 API

  • 財政部加密用 Key
    財政部提供的 HMAC-SHA1 加密用 AppKey

  • Api 位置
    呼叫的 API 位置

  • Request
    傳送給財政部的資料

使用方法

  1. 開啟 /src/appsettings.json
  2. 將財政部提供的 AppKeyAppID 填上去
  3. 用 Visual Studio 2017 開啟並執行即可 !!

Api 新增

開啟 /src/Json/ApiList.json 且依照下面的參數新增 Api

參數介紹

參數名稱 參數說明
TypeName Api 類型 (依此欄位排序)
ApiName Api 名稱
ApiUrl Api 位置
Param Api 需傳送的參數範本 (參數 timeStamp, expTimeStamp, uuid, appID 會被自動取代)
       

[C#][LeetCode][Easy] 657. Judge Route Circle

心得:

控制機器人走路,且最後必須回到起點,把它當作XY軸來理解的話很快就可以解答。
右 X + 1, 左 X – 1, 上 Y + 1, 下 Y – 1,最後 X 與 Y 皆為0則回傳true

問題:

Initially, there is a Robot at position (0, 0). Given a sequence of its moves, judge if this robot makes a circle, which means it moves back to the original place.

The move sequence is represented by a string. And each move is represent by a character. The valid robot moves are R (Right), L (Left), U (Up) and D (down). The output should be true or false representing whether the robot makes a circle.

Example 1:

Input: "UD"
Output: true

Example 2:

Input: "LL"
Output: false

答案:

public class Solution {
    public bool JudgeCircle(string moves) {
        int x = 0;
        int y = 0;

        foreach (var item in moves)
        {
            switch (item)
            {
                case 'U':
                    {
                        y++;
                        break;
                    }
                case 'D':
                    {
                        y--;
                        break;
                    }
                case 'R':
                    {
                        x++;
                        break;
                    }
                case 'L':
                    {
                        x--;
                        break;
                    }
            }
        }

        return (x == 0 && y == 0);
    }
}

答案 – Linq:

public class Solution {
    public bool JudgeCircle(string moves) {
        int x = moves.Where(p => p == 'U' || p == 'D').Sum(p => (p == 'U') ? 1 : -1);
        int y = moves.Where(p => p == 'R' || p == 'L').Sum(p => (p == 'R') ? 1 : -1);
        return x == 0 && y == 0;
    }
}

 

       

[C#][ASP.NET WebAPI] 回傳 JSON 時忽略 null 欄位

當回傳JSON格式時通常都會直接傳送model,但又不是每個欄位都有用到就有會空值的欄位出現,這時想要將null的欄位隱藏就可以用這招啦。

 

在WebApiConfig.cs中的Register方法加入以下程式碼:

//回傳時忽略null欄位
config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings
{
    NullValueHandling = NullValueHandling.Ignore
};