瀏覽標籤:

C#

[C#][LeetCode][Easy] 344. Reverse String

心得:

非常單純的一題,把字串反轉過來就好了,一開始我的Code如下:

public class Solution {
    public string ReverseString(string s) {
        string str = "";
        for(int i = 0; i < s.Length; i++){
            str = s[i] + str;
        }
        
        return str;
    }
}

結果最後一個測試沒過顯示Time Out,我才發現我完全沒有考慮到校能問題…

就算用StringBuilder依然不會過…

拜大神才發現原來有Array.Reverse這個方法可以用,而且又好維護 !太神辣!

問題:

Write a function that takes a string as input and returns the string reversed.

答案:

  1. Array.Reverse
    public class Solution {
        public string ReverseString(string s) {
            char[] arr = s.ToCharArray();
            Array.Reverse(arr);
            return new string(arr);
        }
    }
  2. LinQ
    public class Solution {
        public string ReverseString(string s) {
            return new string(s.Reverse().ToArray());
        }
    }

     

參考資料:

  1. Best way to reverse a string
  2. Property or indexer ‘string.this[int]’ cannot be assigned to — it’s read only
       

[C#][LeetCode][Easy] 387. First Unique Character in a String

心得:

題目要我們找出字串中第一個沒有重複的字母索引值,如找不到則回傳-1。

不知道是太久沒有寫程式了還是怎樣,這題我卡好久,最後偷喵了一下Top Solutions才發現原來這麼簡單,IndexOf這個方法可以找到從開始到結束的第一個字串,LastIndexOf方法則可以找到從結束到開始的第一個字串,若這兩個值相等的話不就代表著沒有重複嗎!

問題:

Given a string, find the first non-repeating character in it and return it’s index. If it doesn’t exist, return -1.

答案:

public class Solution {
    public int FirstUniqChar(string s) {
        for(int i = 0;i < s.Length; i++){
            if(s.IndexOf(s[i]) == s.LastIndexOf(s[i])){
                return i;
            }
        }
        
        return -1;
    }
}

 

       

[C#][LeetCode][Easy] 412. Fizz Buzz

心得:

這題也滿簡單用迴圈跑1~n,如果是3的的倍數則將Fizz加入陣列,5的倍數則將Buzz加入陣列,同時是3與5的倍數的話則將FizzBuzz加入陣列,其餘則加入i。

 

題目:

Write a program that outputs the string representation of numbers from 1 to n.

But for multiples of three it should output “Fizz” instead of the number and for the multiples of five output “Buzz”. For numbers which are multiples of both three and five output “FizzBuzz”.

答案:

public class Solution {
    public IList<string> FizzBuzz(int n) {
        List<string> ans = new List<string>();
        for(int i = 1 ; i <= n ; i++ ){
            if(i > 2){
                if(i % 3 == 0 && i % 5 == 0){
                    ans.Add("FizzBuzz");
                }else if(i % 3 == 0){
                    ans.Add("Fizz");
                }else if(i % 5 == 0){
                    ans.Add("Buzz");
                }else{
                    ans.Add(i.ToString());
                }
            }else{
                ans.Add(i.ToString());
            }
        }
        
        return ans;
    }
}

 

       

[C#][LeetCode][Easy] 1. Two Sum

心得:

滿基本的一題,只是我的方法有點爛XD

 

題目:

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution.

答案:

public class Solution {
    public int[] TwoSum(int[] nums, int target) {
        for(int i = 0; i < nums.Length; i++){
            for(int j = i + 1 ; j < nums.Length; j++){
                if(nums[i] + nums[j] == target){
                    return new int[]{i, j};
                }
            }
        }
        
        throw new Exception("error");
    }
}

 

       

[C#][LeetCode][Easy] 461. Hamming Distance

心得:

剛開始看到題目的時候,突然發現我連Hamming Distance是什麼都不清楚,Google一下才知道,原來是把一數字轉成二進位,並依序比對是否相異,如101010與111010紅色標記的地方不一樣,則距離為一,有了起頭後就好解決了 !!

 

題目:

The Hamming distance between two integers is the number of positions at which the corresponding bits are different.

Given two integers x and y, calculate the Hamming distance.

答案:

public class Solution {
    public int HammingDistance(int x, int y) {
        int ans = 0;
        string num_1 = Convert.ToString(x, 2);
        string num_2 = Convert.ToString(y, 2);
        if ( num_1.Length != num_2.Length ){
            if ( num_1.Length > num_2.Length ){
                int diff = num_1.Length - num_2.Length;
                for ( int i = 0 ; i < diff ; i++){
                    num_2 = "0" + num_2;
                }
            }else{
                int diff = num_2.Length - num_1.Length;
                for ( int i = 0 ; i < diff ; i++){
                    num_1 = "0" + num_1;
                }
            }
        }
        for( int i = 0 ; i < num_1.Length; i++ ){
            if( num_1[i] != num_2[i] ){
                ans++;
            }
        }
        
        return ans;
    }
}

 

 

參考網站:

  1. Hamming distance
  2. [C#] 轉2進位 / 10進位 / 16進位

 

 

 

       

[C#][ASP.NET MVC5] 繼承 ValidationAttribute 簡單實作表單欄位驗證

有用過MVC的人一定都知道只要在Model上面加標籤[Required],即可達到前後端驗證欄位必填的效果,無聊研究了一下來簡單實作自定義的表單欄位驗證 !!

 

  1. 首先建立一個類別,繼承ValidationAttribute,宣告m_BaseText變數來儲存預設禁止的文字,而m_Text則是用來儲存禁止其他文字用的變數。
    public class ExampleAttribute : ValidationAttribute
    {
    	private string[] m_Text;
    	private string[] m_BaseText = new string[] { @"\", @"/", @"<", @">" };
    }
  2. 接下來利用多載宣告兩個建構子,一個是不帶參數的,另一則是型別為string[]Text變數,並放到剛剛宣告的m_Text裡面。
    public ExampleAttribute()
    {
    	m_Text = new string[] { };
    }
    
    public ExampleAttribute(string[] Text)
    {
    	this.m_Text = Text;
    }
  3. 接下來把IsValid方法override掉,並實作驗證機制。
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
    	string strValue = (string)value;
    	string[] strBaseError = m_BaseText.Where(x => strValue.Contains(x)).ToArray();
    	string[] strCustomError = m_Text.Where(x => strValue.Contains(x)).ToArray();
    
    	if (strBaseError.Count() == 0 && strCustomError.Count() == 0)
    	{
    		return ValidationResult.Success;
    	}
    	else
    	{
    		List<string> temp = new List<string>();
    		temp.AddRange(m_BaseText.ToList());
    		temp.AddRange(m_Text.ToList());
    		string errorMsg = $"禁止輸入 [{string.Join(", ", temp.ToArray())}] !!";
    		return new ValidationResult(errorMsg);
    	}
    }
    
  4. 完成 !!
    2016-09-26-23_22_37-example-%e6%88%91%e7%9a%84-asp-net-%e6%87%89%e7%94%a8%e7%a8%8b%e5%bc%8f

    2016-09-26-23_29_45-example-%e6%88%91%e7%9a%84-asp-net-%e6%87%89%e7%94%a8%e7%a8%8b%e5%bc%8f

原始碼:https://github.com/shuangrain/WebApplication_CustomAttribute

       

[C#][ASP.NET WebAPI] 修改預設回傳格式為Json

最近在玩ASP.NET Web API,他不但支援Json也支援Xml,但預設回傳的格式是Xml怎麼辦?

 

檔案位置:~/App_Start/WebApiConfig.cs

//預設回傳Json
MediaTypeHeaderValue appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);

 

參考:

       

[C#] 利用 interface(介面) abstract(抽象) override(覆寫) inherit(繼承) 實作簡單範例

來源:

  1. (原創) interface和abstract class有何不同? (C/C++) (.NET) (C#)
  2. [C#] abstract 和 virtual 函數的差異

 

這篇真的寫得很棒,大家一定要點進去看看,並自己動手寫Code !!
而我自己寫一篇只是為了建檔,方便日後自己觀看用,裡面的Code都是基於上面教學文寫的,自己只是加了一個AutoDoor的功能而已。

 


 

  1. 建立一個abstract的Door類別,裡面有Open(開門)與Close(關門)這兩個虛擬方法可以用
    abstract class Door
    {
        public virtual void Open()
        {
            Console.WriteLine("Open Door");
        }
        public virtual void Close()
        {
            Console.WriteLine("Close Door");
        }
    }
    

     

  2. 建立一個HorizontalDoor類別,它繼承了原先的Door,所以它也有Open與Close這兩個方法可以用
    class HorizontalDoor : Door { }
    

     

  3. 建立一個VerticalDoor類別,它也繼承了Door,可是我在裡面override了原先的Open與Close,另外實作其方法
    class VerticalDoor : Door
    {
        public override void Open()
        {
            Console.WriteLine("Open vertically");
        }
        public override void Close()
        {
            Console.WriteLine("Close vertically");
        }
    }
    

     

  4. 建立一個IAlarm介面,裡面定義了Alert這個方法
    interface IAlarm
    {
        void Alert();
    }
    

     

  5. 建立一個Alarm類別,它繼承了IAlarm,並在裡面實作Alert
    class Alarm : IAlarm
    {
        public void Alert()
        {
            Console.WriteLine("Ring ~~");
        }
    }
    

     

  6. 建立一個AlarmDoor類別,它繼承了Door,同時在裡面使用了Alarm類別的Alert方法
    class AlarmDoor : Door
    {
        private IAlarm _alarm;
    
        public AlarmDoor()
        {
            _alarm = new Alarm();
        }
    
        public void Alert()
        {
            _alarm.Alert();
        }
    }
    

     

  7. 建立一個AutoAlarmDoor類別,它繼承了AlarmDoor,並覆寫了原本的Open方法,裡面呼叫base.Open方法並接著呼叫Alert方法
    class AutoAlarmDoor : AlarmDoor
    {
        public override void Open()
        {
            base.Open();
            Alert();
        }
    }
    

     

  8. 建立一個DoorController類別,這個類別是用來控制管理所有的Door
    class DoorController
    {
        protected List<Door> _dootList = new List<Door>();
    
        public void AddDoor(Door Door)
        {
            _dootList.Add(Door);
        }
    
        public void OpenDoor()
        {
            foreach (var item in _dootList)
            {
                item.Open();
            }
        }
    }
    

     

  9. 完成 !!
    static void Main(string[] args)
    {
        DoorController dc = new DoorController();
        dc.AddDoor(new HorizontalDoor());
        dc.AddDoor(new VerticalDoor());
        dc.AddDoor(new AlarmDoor());
        dc.AddDoor(new AutoAlarmDoor());
    
        dc.OpenDoor();
    
        Console.ReadLine();
    }

     

  10. 執行結果
    2016-09-07 23_06_31-file____C__Users_Minsheng_Desktop_ConsoleApplication_Door_ConsoleApplication_Doo

 

  • 注意事項
    1. abstract method 不會有程式內容
    2. abstract method 繼承後,一定要 override
    3. virtual method 一定要有程式內容
    4. 宣告為 virtual 的 method,繼承後才可以進行 override
    5. 設定為 virtual 的 method,沒有一定要 override

 

       

[C#] 複製 Model 後異動時會互相引響

有一需求必須複製一個Model,這時如果異動Model_Copy時會造成Model_Source也跟著被更動,爬文後找到了一些方法來測試,問題依然存在…

 

  1. 用等於(=)的方式取值
    • 程式碼
      2016-08-25 22_03_12-ConsoleApplication1 - Microsoft Visual Studio
    • 結果:
      2016-08-25 22_03_39-file____C__Users_Minsheng_Desktop_ConsoleApplication1_ConsoleApplication1_bin_De
  2. 用new建立新的物件的方式取值
    • 程式碼
      2016-08-25 22_06_46-ConsoleApplication1 [執行] - Microsoft Visual Studio
    • 結果
      2016-08-25 22_03_39-file____C__Users_Minsheng_Desktop_ConsoleApplication1_ConsoleApplication1_bin_De
  3. 利用LINQ的方式取值
    • 程式碼
      2016-08-25 22_08_09-ConsoleApplication1 [執行] - Microsoft Visual Studio
    • 結果
      2016-08-25 22_03_39-file____C__Users_Minsheng_Desktop_ConsoleApplication1_ConsoleApplication1_bin_De

 

最後終於找到了一個方法可以用,那就是讓Model繼承ICloneable並使用Object中的MemberwiseClone()來實作Clone(),就可以順利Copy啦!

  • 程式碼
    1. Model
      2016-08-25 22_11_30-ConsoleApplication1 [執行] - Microsoft Visual Studio
    2. 利用LINQ來呼叫Clone()方法
      2016-08-25 22_46_21-ConsoleApplication1 - Microsoft Visual Studio
  • 結果
    2016-08-25 22_15_03-file____C__Users_Minsheng_Desktop_ConsoleApplication1_ConsoleApplication1_bin_De

 

       

[C#] 使用 AutoMapper 快速轉換有相同資料的 Model

因為工作因素發生了需要將兩個具有相同資料的Model進行轉換,但是如果手動轉換的話太累了,工程師就是懶嘛~
於是乎就拜了Google大神找到了一個名叫AutoMapper套件。

 

  1. 從NuGet下載AutoMapper
    01
  2. 新增兩組相同的Model
    class Model_1
    {
    	public string Name { get; set; }
    
    	public int Year { get; set; }
    
    	public DateTime Date { get; set; }
    }
    
    class Model_2
    {
    	public string Name { get; set; }
    
    	public int Year { get; set; }
    
    	public DateTime Date { get; set; }
    }
    
  3. 轉換用的方法
    static TModel_2 ConvertModelToModel<TModel_1, TModel_2>(TModel_1 list)
    {
    	Mapper.Initialize(cfg =>
    	{
    		cfg.CreateMissingTypeMaps = true;
    		cfg.CreateMap<TModel_1, TModel_2>().ReverseMap();
    	});
    	Mapper.Configuration.AssertConfigurationIsValid();
    
    	var converted = Mapper.Map<TModel_2>(list);
    	return converted;
    }
  4. 轉換
    static void Main(string[] args)
    {
    	Model_1 model1 = new Model_1();
    	Model_2 model2 = new Model_2();
    
    
    	model1.Name = "王小明";
    	model1.Year = 2016;
    	model1.Date = DateTime.UtcNow.AddHours(8);
    
    
    	Console.WriteLine("=== 轉換前 ===");
    	Console.WriteLine("model1=name:{0}, year:{1}, date:{2}, type:{3}", model1.Name, model1.Year, model1.Date, model1.GetType());
    	Console.WriteLine("model2=name:{0}, year:{1}, date:{2}, type:{3}", model2.Name, model2.Year, model2.Date, model2.GetType());
    
    	model2 = ConvertModelToModel<Model_1, Model_2>(model1);
    
    	Console.WriteLine("=== 轉換後 ===");
    	Console.WriteLine("model1=name:{0}, year:{1}, date:{2}, type:{3}", model1.Name, model1.Year, model1.Date, model1.GetType());
    	Console.WriteLine("model2=name:{0}, year:{1}, date:{2}, type:{3}", model2.Name, model2.Year, model2.Date, model2.GetType());
    
    	Console.ReadLine();
    }
  5. 結果
    02

 

原始碼:https://github.com/shuangrain/ConsoleApplication_AutoMapper