none
C# 車牌號碼例如:ABC-123,取其中五碼來比對資料庫問題 RRS feed

  • 問題

  •  大家好,第一次發問,有什麼不對請糾正,感謝

    重點就是車牌辨識到的號碼假設是 OBC-123 ,但實際車牌號碼是ABC-123,所以我要用五碼比對方法,六碼裡面有五碼對就可以,七碼有六碼就算驗證通過

    下面我寫到 我把輸入的車牌號碼 一個一個字丟到陣列//ppgg

    然後我先判斷 我輸入的車牌號碼和已經丟到LIST的資料庫長度一不一樣,

    一樣之後就是要判斷它們每個位置相不相同,然後我就卡在最下面那行有解說,另外當車牌號碼變為六碼七碼時,不知道該如何判斷和寫出(?XXXXX、X?XXXXX、XX?XXXX)

    C# 和SQL 都行,

    還有就是這種關鍵字該怎麼找,找到的全部都是車牌辨識影像的解說,感謝各位大大



    {

                    try
                    {
                        //連結車牌資料庫
                        SqlCommand comm = new SqlCommand("select * from tbl_Contact", sqlCon);
                        //開啟資料庫
                        sqlCon.Open();
                        //讀取資料
                        SqlDataReader reader = comm.ExecuteReader();
                        //LIST 用來存取SQL裡面的資料
                        List<string> carNumberList = new List<string>();
                        //讀SQL讀到底
                        while (reader.Read())
                        {
                            carNumberList.Add(reader.GetString(0));//抓第幾欄資料進去str                    
                        }
                        int carNumberLength = 0;                 
                        string carNumber = "";
                        //輸入車號識別號碼的長度
                        carNumberLength = (txtSearch.Text.Trim()).Length;
                        //車牌號碼
                        carNumber = txtSearch.Text.Trim();
                        //宣告單個車牌號碼的陣列
                        string[] ppgg = new string[carNumberLength - 1];                    
                        //車牌號碼一字一字塞入陣列去
                        for (int i = 0; i < carNumberLength; i++)
                        {
                            ppgg[i] = carNumber.Substring(i,1);                        
                        }
                        //對資料庫進行比對
                        for (int i = 0; i < carNumberList.Count; i++)
                        {
                            //判斷車牌和資料庫長度一不一樣
                            if (carNumberLength == carNumberList[i].Length)  
                            {
                                //進行少一碼驗證比對資料
                                for (int ii = 0; ii < carNumberLength; ii++)
                              {
                        //4碼車牌的話,進行4次迴圈 ?XXX、X?XX、XX?X、XXX? 和資料庫進行比對,這邊我不知道怎麼寫?????
                              }
                            }                       
                        }


                        reader.Close();                  

                    }

                    catch (Exception ex)//這欄為發生意外要乾麻
                    {
                        MessageBox.Show(ex.Message, "error message");
                    }
                    finally//最後要乾麻 
                    {
                        sqlCon.Close();//關閉資料庫,
                    }



                }

                                    
    2017年5月9日 上午 08:13

解答

  • 2000 筆的話倒是有比較勞苦的方式可以做

    (1) 我們假設車牌辨識出來幾位數,比如 OBC-123,就確認只會辨識七個字(包含 - 號)

    (2) 所以從資料庫只要先撈該長度為 7 的資料即可

    (3) 接著用 linq 的 ToArray()。把 OBC-123 變成一個 Char 陣列 [O],[B],[C],[-],[1],[2],[3]

    (4) 把那一群從資料庫撈回的資料使用 for 或是 freach 做比對

    (5) 撈回的第一筆也是 ToArray() ,這樣你就可以用個 for 迴圈確定有幾個 Char 是同一個位置又相同的

    (6) 依此要領跑到底,答案就出來了。


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    • 已標示為解答 pigpp 2017年5月10日 上午 03:57
    2017年5月9日 下午 01:03
    版主
  • ?????

    • 已標示為解答 pigpp 2017年5月10日 下午 01:21
    • 已編輯 [-] 2018年1月11日 上午 11:47
    2017年5月10日 下午 12:09

所有回覆

  • 我想到的笨方法,把 OBC-123 用程式把查詢條件產出來後,送進資料庫去做 LIKE 的查詢。

    *** 切記要用參數化,避免 SQL injection。

    SELECT [Id]
          ,[Num]
      FROM [Test].[dbo].[Car]
      where 
    	 (num like '%BC-123'
      or num like '%BC-123'
      or num like 'O%C-123'
      or num like 'OB%-123'
      or num like 'OBC-%23'
      or num like 'OBC-1%3'
      or num like 'OBC-12%')
      and len(num) = 7 

    2017年5月9日 上午 08:38
  • 謝謝回覆~不過這個車牌號碼不止有OBC-123而已 ,是隨機性,就是車牌辨識影像已經有了,他辨別的車牌有4-7碼的,我要從他辨別的資料庫裡面去撈出來比對
    2017年5月9日 上午 08:56
  • 這取決一個問題,資料庫裡有的車牌有多少個 ? 會不會無限大一直增長 ? 還是固定不變的?

    因為我看到你的 DataReader 是整個把資料庫讀回來.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2017年5月9日 上午 09:31
    版主
  • Bill Chung 大您好

    對,因為我資料庫是做成用winform可以增刪查改的管理名單,主要就是輸入用戶車牌資料然後進行比對,但理論上應該是不會很大,2000筆左右吧,要新增停車車牌名單和黑名單之類的。

    2017年5月9日 上午 09:41
  • 謝謝回覆~不過這個車牌號碼不止有OBC-123而已 ,是隨機性,就是車牌辨識影像已經有了,他辨別的車牌有4-7碼的,我要從他辨別的資料庫裡面去撈出來比對

     input 當然不只 OBC-123,你要用程式去做處理。

    即使現在的 input 是 AB-12 或是 WSXE-345 應該都可以用程式 把車牌加上% 然後去 LIKE 查詢。

    2017年5月9日 上午 09:46
  • 2000 筆的話倒是有比較勞苦的方式可以做

    (1) 我們假設車牌辨識出來幾位數,比如 OBC-123,就確認只會辨識七個字(包含 - 號)

    (2) 所以從資料庫只要先撈該長度為 7 的資料即可

    (3) 接著用 linq 的 ToArray()。把 OBC-123 變成一個 Char 陣列 [O],[B],[C],[-],[1],[2],[3]

    (4) 把那一群從資料庫撈回的資料使用 for 或是 freach 做比對

    (5) 撈回的第一筆也是 ToArray() ,這樣你就可以用個 for 迴圈確定有幾個 Char 是同一個位置又相同的

    (6) 依此要領跑到底,答案就出來了。


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    • 已標示為解答 pigpp 2017年5月10日 上午 03:57
    2017年5月9日 下午 01:03
    版主
  • 謝謝Bill Chung大 

    對其他大大的回覆也很感激,SQL預存程序剛學,所以還是用了C#,大概會很佔效能吧~~?

    .ToCharArray 還在迷迷糊糊不太了解,覺得好難,大概CODE太少了

    大概講解一下,沒有要用車牌長度去辨識,而是以輸入的車牌號碼中間的"-"做基準分左右半部,左半部反轉字串在裝進陣列中,之後跟資料庫 左半部(FOR迴圈) 在右半部(FOR迴圈)比對位置, 相同位置內,字串相同就加一分。

    會以"-"辨識原因,主要是辨識的車牌可能長度也不準確,所以以"-"為基準左右兩邊去辨識,難怪我網路查五碼辨識四碼的資料都找不到,寫完才發現,這根本初級不到的東西,幾個迴圈就搞定了,撲撲= ="

    原本我是想把SQL車牌資料全部一起分左右半部,然後左半部反轉,但沒想出來,可能要用到二維陣列,恩..不確定

    //連結車牌資料庫
                        SqlCommand comm = new SqlCommand("select * from tbl_Contact", sqlCon);
                        //開啟資料庫
                        sqlCon.Open();
                        //讀取資料
                        SqlDataReader reader = comm.ExecuteReader();
                        //LIST 用來存取SQL裡面的資料
                        List<string> sqlcarNumberList = new List<string>();
                        //讀SQL讀到底
                        while (reader.Read())
                        {
                            sqlcarNumberList.Add(reader.GetString(0));//抓第幾欄資料進去str                    
                        }       
                        int carNumberLength = 0;
                        string carNumber = "";                  
                        //車牌號碼
                        carNumber = txtSearch.Text.Trim();                  
                       //輸入車號識別號碼的長度
                        carNumberLength = (txtSearch.Text.Trim()).Length;
                       //車牌號碼分兩部分
                        Char delimiter = '-';
                        String[] substrings = carNumber.Split(delimiter);
                        char[] carNpart1 = substrings[0].ToCharArray();//車牌左半段
                        char[] carNpart2 = substrings[1].ToCharArray();//車牌右半段
                        //反轉整個字串陣列的順序
                        Array.Reverse(carNpart1);
                        //從SQL第一筆車號開始掃描
                        //以"-"先分割資料庫車牌號碼前後半段,前半段要反轉
                         for (int i = 0; i < sqlcarNumberList.Count; i++)
                         {
                             //a=對中一碼+1分上去
                             int  aPoint = 0;
                             //宣告sqlCN=資料庫的車牌號碼
                             String[] sqlCN = sqlcarNumberList[i].Split(delimiter);
                             char[] sqlCarNpart1 = sqlCN[0].ToCharArray();//SQL車牌左半部
                             char[] sqlCarNpart2 = sqlCN[1].ToCharArray();//SQL車牌右半部
                             //反轉SQL整個字串陣列的順序
                             Array.Reverse(sqlCarNpart1);

                             //車牌左邊 跟SQL車牌前半段對比                    
                             for(int ii = 0; ii < carNpart1.Length; ii++)
                             {
                                 if (carNpart1[i] == sqlCarNpart1[i])
                                 {
                                     aPoint++;
                                 }
                             }
                             //車牌右邊 跟SQL車牌前半段對比                   
                             for (int ii = 0; ii < carNpart2.Length; ii++)
                             {
                                 if (carNpart2[i] == sqlCarNpart2[i])
                                 {
                                     aPoint++;
                                 }
                             }
                             //設定apoint要幾分以上。讓車車通過

                         }

    2017年5月10日 上午 04:02
  • 為什麼前半段要反轉 ? 這有甚麼特別原因嗎 ? 因為你兩個都反轉後比對,不就和沒反轉比對是一樣的道理嗎 ? (單純好奇)


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2017年5月10日 上午 08:54
    版主
  • F大您好,謝謝指正

    對的~我剛剛才把它修正完,直接左右半部迴圈外面再加上IF.ELSE  判斷 如果carNpart1.lenth>sqlCarNpart1.lenth  

    迴圈就使用sqlCarNpart1.lenth  當最大值

    至於拆分的話,是想到當掃描的車牌號碼如果沒掃好,例如車牌本身是ABC-123,結果掃描到BC-123,那我先用長度比對的話,就會比不到,所以以"-"為基準


    //車牌左邊 跟SQL車牌前半段對比  
                             if (carNpart1.Length < sqlCarNpart1.Length)
                             {
                                 for(int i1 = 0; i1 < carNpart1.Length; i1++)
                                 {
                                     if (carNpart1[i1] == sqlCarNpart1[i1])
                                     {
                                         aPoint++;
                                     }
                                 }
                             }
                             else
                             {
                                 for (int i1 = 0; i1 < sqlCarNpart1.Length; i1++)
                                 {
                                     if (carNpart1[i1] == sqlCarNpart1[i1])
                                     {
                                         aPoint++;
                                     }
                                 }
                             }


    • 已編輯 pigpp 2017年5月10日 上午 09:23 改字...
    2017年5月10日 上午 09:02
  • Bill Chung您好,

    只有反轉前半部,怕遇到車牌掃描 掃到BC-123 ,實際車牌(資料庫資料)是ABC-123  那比對的話 前半部BC裝陣列會是[0]=B  [1]=C  , 資料庫車牌前半部會是[0]=A ,[1]=B,[2]=3 ,比對就會不准

    全部都是基於車牌掃瞄不準,得到的車牌長度不一樣時,所以才以"-"為基準去判定。



    • 已編輯 pigpp 2017年5月10日 上午 09:16 改字
    2017年5月10日 上午 09:09
  • 所以這問題挺有趣的。容我問清楚一點

    如果正確的車牌是 ABC-123

    我們只看英文字好了,所以有可能出現

    (1) AB

    (2) AC

    (3) BC

    這三種情況嗎? 也就是有可能連中間的 B 都會被跳過? 還是只會跳過 前和後 ?


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2017年5月10日 上午 09:22
    版主
  • Bill Chung您好,

    我想這要看車牌辨識寫的好不好,基本上ABC-123 去做辨識的話,如果角度沒拍好之類的 是有可能遮到左右各一碼的,所以分析出AB、AC不太可能,BC比較可能,因為A可能角度問題沒拍好。

    但如果是OCQ車牌加上角度沒拍好, 就有可能出現您說的三種情況。

    所以車牌辨識,會拍好幾張,一張通過驗證,就OK


    • 已編輯 pigpp 2017年5月10日 上午 09:47 少打字
    2017年5月10日 上午 09:46
  • ?????

    • 已標示為解答 pigpp 2017年5月10日 下午 01:21
    • 已編輯 [-] 2018年1月11日 上午 11:47
    2017年5月10日 下午 12:09
  • 謝謝F大指點

    我不會用效能問題~還有其他空白也沒注意到

    待我研究研究你建議的程式碼,感恩


    • 已編輯 pigpp 2017年5月10日 下午 12:27
    2017年5月10日 下午 12:27