如何将配对值从文本框保存到数据库分隔的单词和计数 [英] How can I save pair values from textbox to a database separated word and count
本文介绍了如何将配对值从文本框保存到数据库分隔的单词和计数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想插入单词和计数器字段,但首先我想得到对的值和键分隔,因为单词字段将存储输入键,而计数字段将存储输入值
我尝试了什么:
I want to insert into word and counter field but first I want to get pair values and key separated as word field will store entry key and Count Field will store entry value
What I have tried:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Data.SqlClient;
namespace ListWordsByFrequency
{
public partial class Form1 : Form
{
/// <summary>
/// An enumeration of sorting options to be used.
/// </summary>
private enum SortOrder
{
Ascending, // from small to big numbers or alphabetically.
Descending // from big to small number or reversed alphabetical order
}
// This will discard digits
private static char[] delimiters_no_digits = new char[] {
'{', '}', '(', ')', '[', ']', '>', '<','-', '_', '=', '+',
'|', '\\', ':', ';', '"', ',', '.', '/', '?', '~', '!',
'@', '#', '$', '%', '^', '&', '*', ' ', '\r', '\n', '\t',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
};
///
public Form1()
{
InitializeComponent();
}
/// <summary>
/// Tokenizes a text into an array of words, using the improved
/// tokenizer with the discard-digit option.
/// </summary>
/// <param name="text">the text to tokenize</param>
private string[] Tokenize(string text)
{
string[] tokens = text.Split(delimiters_no_digits, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < tokens.Length; i++)
{
string token = tokens[i];
// Change token only when it starts and/or ends with "'" and
// it has at least 2 characters.
if (token.Length > 1)
{
if (token.StartsWith("'") && token.EndsWith("'"))
tokens[i] = token.Substring(1, token.Length - 2); // remove the starting and ending "'"
else if (token.StartsWith("'"))
tokens[i] = token.Substring(1); // remove the starting "'"
else if (token.EndsWith("'"))
tokens[i] = token.Substring(0, token.Length - 1); // remove the last "'"
}
}
return tokens;
}
/// <summary>
/// Make a string-integer dictionary out of an array of words.
/// </summary>
/// <param name="words">the words out of which to make the dictionary</param>
/// <returns>a string-integer dictionary</returns>
private Dictionary<string, int> ToStrIntDict(string[] words)
{
Dictionary<string, int> dict = new Dictionary<string, int>();
foreach (string word in words)
{
// if the word is in the dictionary, increment its freq.
if (dict.ContainsKey(word))
{
dict[word]++;
}
// if not, add it to the dictionary and set its freq = 1
else
{
dict.Add(word, 1);
}
}
return dict;
}
/// <summary>
/// Sort a string-int dictionary by its entries' values.
/// </summary>
/// <param name="strIntDict">a string-int dictionary to sort</param>
/// <param name="sortOrder">one of the two enumerations: Ascening and Descending</param>
/// <returns>a string-integer dictionary sorted by integer values</returns>
private Dictionary<string, int> ListWordsByFreq(Dictionary<string, int> strIntDict, SortOrder sortOrder)
{
// Copy keys and values to two arrays
string[] words = new string[strIntDict.Keys.Count];
strIntDict.Keys.CopyTo(words, 0);
int[] freqs = new int[strIntDict.Values.Count];
strIntDict.Values.CopyTo(freqs, 0);
//Sort by freqs: it sorts the freqs array, but it also rearranges
//the words array's elements accordingly (not sorting)
Array.Sort(freqs, words);
// If sort order is descending, reverse the sorted arrays.
if (sortOrder == SortOrder.Descending)
{
//reverse both arrays
Array.Reverse(freqs);
Array.Reverse(words);
}
//Copy freqs and words to a new Dictionary<string, int>
Dictionary<string, int> dictByFreq = new Dictionary<string, int>();
for (int i = 0; i < freqs.Length; i++)
{
dictByFreq.Add(words[i], freqs[i]);
}
return dictByFreq;
}
// Load file to input box
private void btnLoadFile_Click(object sender, EventArgs e)
{
OpenFileDialog openDlg = new OpenFileDialog();
if (openDlg.ShowDialog() == DialogResult.OK)
{
textBoxInput.Text = File.ReadAllText(openDlg.FileName);
}
}
// Process input box text and display result in output box
private void btnExecute_Click(object sender, EventArgs e)
{
if (textBoxInput.Text != string.Empty)
{
// Split text into array of words
string[] words = Tokenize(textBoxInput.Text);
if (words.Length > 0)
{
// Make a string-int dictionary out of the array of words
Dictionary<string, int> dict = ToStrIntDict(words);
// Set SortOrder based on user's choice.
//
// The follow code is the compact form of:
// if radioButtonAscending is Checked, sortOrder = SortOrder.Ascending
// else sortOrder = SortOrder.Descending
//
SortOrder sortOrder = radioButtonAscending.Checked ? SortOrder.Ascending : SortOrder.Descending;
// Sort dict by values
dict = ListWordsByFreq(dict, sortOrder);
// Dump dict entries to a StrinbBuilder for efficiency.
StringBuilder resultSb = new StringBuilder(dict.Count * 9);
foreach (KeyValuePair<string, int> entry in dict)
resultSb.AppendLine(string.Format("{0} [{1}]", entry.Key, entry.Value));
// Put the content of the StringBuilder in the Output box
textBoxOutput.Text = resultSb.ToString();
try
{
// SqlConnection conn = new SqlConnection(@"Data Source=samkelo.database.windows.net;Initial Catalog=Samkelo;Persist Security Info=True;User ID=****;Password=*****");
SqlConnection conn = new SqlConnection(@"Data Source=####-PC\SQLEXPRESS;Initial Catalog=Assessmenet;Integrated Security=True");
SqlCommand cmd = new SqlCommand("INSERT INTO WordCount(Word,Count)" + "INSERT
//here is my problem I want to insert this values separetely from a database table word to Word field and a number to count field? INTO WordCount(Word,Count)VALUES ('{0},entry.Key', '[{1}],entry.Value')", conn);
conn.Open();
cmd.ExecuteNonQuery();
MessageBox.Show("Connection Succeful");
}
catch (SqlException ex)
{
MessageBox.Show("There is an Error" + ex);
}
finally
{
// conn.Close();
MessageBox.Show("Connection Closed");
}
}
}
}
}
}
推荐答案
',' %',' ^',' & ;',' *',' ',' \ r',' \ n',' \t',
' 0',' 1', ' 2',' 3',' 4',' 5',' 6',' 7',' 8',' 9'
};
///
public Form1()
{
InitializeComponent();
}
/// < 摘要 >
/// 使用改进的
/// 带有discard-digit选项的tokenizer。
/// < / summary >
/// < param < span class =code-summarycomment> name =text > 文本标记化< / param >
private string [] Tokenize( string text)
{
string [] tokens = text.Split(delimiters_no_digits,StringSplitOptions.RemoveEmptyEn尝试);
for ( int i = 0 ; i < tokens.Length; i ++)
{
string token = tokens [i];
// 仅在启动和/或以'和<结尾时更改令牌/ span>
// 它至少包含2个字符。
if (token.Length > 1 )
{
if (token.StartsWith( )&& token.EndsWith( ') )
tokens [i] = token.Substring( 1 ,token.Length - 2 ) ; // 删除开头和结尾'
else if (token.StartsWith( '))
tokens [i] = token.Substring( 1 ); // 删除首字母'
else if (token.EndsWith( '))
tokens [i] = token.Substring( 0 ,token.Length - 1 跨度>); // 删除最后一个'
}
}
返回标记;
}
/// < 摘要 >
/// 从一个单词数组中创建一个字符串整数字典。
/// < / summary >
/// < param < span class =code-summarycomment> name =words > 字样在其中制作字典< / param > ;
/// < 返回 > 字符串整数字典< / returns >
private Dictionary< string,int> ToStrIntDict( string [] words)
{
Dictionary< string,int> dict = new Dictionary< string,int>();
foreach ( string word in words)
{
// 如果单词在字典中,增加其频率。
if (dict.ContainsKey(word))
{
dict [word] ++ ;
}
// 如果没有,请将其添加到字典并设置其freq = 1
else
{
dict.Add(word, 1 跨度>);
}
}
return dict;
}
/// < 摘要 >
/// 按字符串的值排序字符串-int字典。
/// < / summary >
/// < param < span class =code-summarycomment> name =strIntDict > 一个字符串-int字典排序< / param >
/// < param name =sortOrder跨度> < span class =code-summarycomment>> 两个枚举中的一个:Ascening和Descending < / param >
/// < 返回 > 按整数值排序的字符串整数字典< / returns >
private Dictionary< string,int> ListWordsByFreq(Dictionary<string, int> strIntDict, SortOrder sortOrder)
{
// Copy keys and values to two arrays
string[] words = new string[strIntDict.Keys.Count];
strIntDict.Keys.CopyTo(words, 0);
int[] freqs = new int[strIntDict.Values.Count];
strIntDict.Values.CopyTo(freqs, 0);
//Sort by freqs: it sorts the freqs array, but it also rearranges
//the words array's elements accordingly (not sorting)
Array.Sort(freqs, words);
// If sort order is descending, reverse the sorted arrays.
if (sortOrder == SortOrder.Descending)
{
//reverse both arrays
Array.Reverse(freqs);
Array.Reverse(words);
}
//Copy freqs and words to a new Dictionary<string, int>
Dictionary<string, int> dictByFreq = new Dictionary<string, int>();
for (int i = 0; i < freqs.Length; i++)
{
dictByFreq.Add(words[i], freqs[i]);
}
return dictByFreq;
}
// Load file to input box
private void btnLoadFile_Click(object sender, EventArgs e)
{
OpenFileDialog openDlg = new OpenFileDialog();
if (openDlg.ShowDialog() == DialogResult.OK)
{
textBoxInput.Text = File.ReadAllText(openDlg.FileName);
}
}
// Process input box text and display result in output box
private void btnExecute_Click(object sender, EventArgs e)
{
if (textBoxInput.Text != string.Empty)
{
// Split text into array of words
string[] words = Tokenize(textBoxInput.Text);
if (words.Length > 0)
{
// Make a string-int dictionary out of the array of words
Dictionary<string, int> dict = ToStrIntDict(words);
// Set SortOrder based on user's choice.
//
// The follow code is the compact form of:
// if radioButtonAscending is Checked, sortOrder = SortOrder.Ascending
// else sortOrder = SortOrder.Descending
//
SortOrder sortOrder = radioButtonAscending.Checked ? SortOrder.Ascending : SortOrder.Descending;
// Sort dict by values
dict = ListWordsByFreq(dict, sortOrder);
// Dump dict entries to a StrinbBuilder for efficiency.
StringBuilder resultSb = new StringBuilder(dict.Count * 9);
foreach (KeyValuePair<string, int> entry in dict)
resultSb.AppendLine(string.Format(\"{0} [{1}]\", entry.Key, entry.Value));
// Put the content of the StringBuilder in the Output box
textBoxOutput.Text = resultSb.ToString();
try
{
// SqlConnection conn = new SqlConnection(@\"Data Source=samkelo.database.windows.net;Initial Catalog=Samkelo;Persist Security Info=True;User ID=****;Password=*****\");
SqlConnection conn = new SqlConnection(@\"Data Source=####-PC\SQLEXPRESS;Initial Catalog=Assessmenet;Integrated Security=True\");
SqlCommand cmd = new SqlCommand(\"INSERT INTO WordCount(Word,Count)\" + \"INSERT
//here is my problem I want to insert this values separetely from a database table word to Word field and a number to count field? INTO WordCount(Word,Count)VALUES ('{0},entry.Key', '[{1}],entry.Value')\", conn);
conn.Open();
cmd.ExecuteNonQuery();
MessageBox.Show(\"Connection Succeful\");
}
catch (SqlException ex)
{
MessageBox.Show(\"There is an Error\" + ex);
}
finally
{
// conn.Close();
MessageBox.Show(\"Connection Closed\");
}
}
}
}
}
}
', '%', '^', '&', '*', ' ', '\r', '\n', '\t', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; /// public Form1() { InitializeComponent(); } /// <summary> /// Tokenizes a text into an array of words, using the improved /// tokenizer with the discard-digit option. /// </summary> /// <param name="text">the text to tokenize</param> private string[] Tokenize(string text) { string[] tokens = text.Split(delimiters_no_digits, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < tokens.Length; i++) { string token = tokens[i]; // Change token only when it starts and/or ends with "'" and // it has at least 2 characters. if (token.Length > 1) { if (token.StartsWith("'") && token.EndsWith("'")) tokens[i] = token.Substring(1, token.Length - 2); // remove the starting and ending "'" else if (token.StartsWith("'")) tokens[i] = token.Substring(1); // remove the starting "'" else if (token.EndsWith("'")) tokens[i] = token.Substring(0, token.Length - 1); // remove the last "'" } } return tokens; } /// <summary> /// Make a string-integer dictionary out of an array of words. /// </summary> /// <param name="words">the words out of which to make the dictionary</param> /// <returns>a string-integer dictionary</returns> private Dictionary<string, int> ToStrIntDict(string[] words) { Dictionary<string, int> dict = new Dictionary<string, int>(); foreach (string word in words) { // if the word is in the dictionary, increment its freq. if (dict.ContainsKey(word)) { dict[word]++; } // if not, add it to the dictionary and set its freq = 1 else { dict.Add(word, 1); } } return dict; } /// <summary> /// Sort a string-int dictionary by its entries' values. /// </summary> /// <param name="strIntDict">a string-int dictionary to sort</param> /// <param name="sortOrder">one of the two enumerations: Ascening and Descending</param> /// <returns>a string-integer dictionary sorted by integer values</returns> private Dictionary<string, int> ListWordsByFreq(Dictionary<string, int> strIntDict, SortOrder sortOrder) { // Copy keys and values to two arrays string[] words = new string[strIntDict.Keys.Count]; strIntDict.Keys.CopyTo(words, 0); int[] freqs = new int[strIntDict.Values.Count]; strIntDict.Values.CopyTo(freqs, 0); //Sort by freqs: it sorts the freqs array, but it also rearranges //the words array's elements accordingly (not sorting) Array.Sort(freqs, words); // If sort order is descending, reverse the sorted arrays. if (sortOrder == SortOrder.Descending) { //reverse both arrays Array.Reverse(freqs); Array.Reverse(words); } //Copy freqs and words to a new Dictionary<string, int> Dictionary<string, int> dictByFreq = new Dictionary<string, int>(); for (int i = 0; i < freqs.Length; i++) { dictByFreq.Add(words[i], freqs[i]); } return dictByFreq; } // Load file to input box private void btnLoadFile_Click(object sender, EventArgs e) { OpenFileDialog openDlg = new OpenFileDialog(); if (openDlg.ShowDialog() == DialogResult.OK) { textBoxInput.Text = File.ReadAllText(openDlg.FileName); } } // Process input box text and display result in output box private void btnExecute_Click(object sender, EventArgs e) { if (textBoxInput.Text != string.Empty) { // Split text into array of words string[] words = Tokenize(textBoxInput.Text); if (words.Length > 0) { // Make a string-int dictionary out of the array of words Dictionary<string, int> dict = ToStrIntDict(words); // Set SortOrder based on user's choice. // // The follow code is the compact form of: // if radioButtonAscending is Checked, sortOrder = SortOrder.Ascending // else sortOrder = SortOrder.Descending // SortOrder sortOrder = radioButtonAscending.Checked ? SortOrder.Ascending : SortOrder.Descending; // Sort dict by values dict = ListWordsByFreq(dict, sortOrder); // Dump dict entries to a StrinbBuilder for efficiency. StringBuilder resultSb = new StringBuilder(dict.Count * 9); foreach (KeyValuePair<string, int> entry in dict) resultSb.AppendLine(string.Format("{0} [{1}]", entry.Key, entry.Value)); // Put the content of the StringBuilder in the Output box textBoxOutput.Text = resultSb.ToString(); try { // SqlConnection conn = new SqlConnection(@"Data Source=samkelo.database.windows.net;Initial Catalog=Samkelo;Persist Security Info=True;User ID=****;Password=*****"); SqlConnection conn = new SqlConnection(@"Data Source=####-PC\SQLEXPRESS;Initial Catalog=Assessmenet;Integrated Security=True"); SqlCommand cmd = new SqlCommand("INSERT INTO WordCount(Word,Count)" + "INSERT //here is my problem I want to insert this values separetely from a database table word to Word field and a number to count field? INTO WordCount(Word,Count)VALUES ('{0},entry.Key', '[{1}],entry.Value')", conn); conn.Open(); cmd.ExecuteNonQuery(); MessageBox.Show("Connection Succeful"); } catch (SqlException ex) { MessageBox.Show("There is an Error" + ex); } finally { // conn.Close(); MessageBox.Show("Connection Closed"); } } } } } }
Instead of creating a StringBuilder, and trying to set that as a string, create a DataTable and use the SqlBulkCopy Class (System.Data.SqlClient)[^] to insert all the rows. The SqlBulkCopy.WriteToServer Method (DataTable) (System.Data.SqlClient)[^] includes an example.
Creating a StringBuilder is not only inefficient, it’s also dangerous - it leaves you wide open to SQL Injection attacks which can damage or destroy your database.
Instead of creating a StringBuilder, and trying to set that as a string, create a DataTable and use the SqlBulkCopy Class (System.Data.SqlClient)[^] to insert all the rows. The SqlBulkCopy.WriteToServer Method (DataTable) (System.Data.SqlClient)[^] includes an example.
Creating a StringBuilder is not only inefficient, it's also dangerous - it leaves you wide open to SQL Injection attacks which can damage or destroy your database.
Using Linq, you can make generating ordered Lists of Key-Value pairs easier:
Using Linq, you can make generating ordered Lists of Key-Value pairs easier:
private IOrderedEnumerable<KeyValuePair<string, int>> CountWords(string text, bool sortedLoHi = true)
{
// get all punctuation and whitespace
var punctuationAndWhiteSpace = text.Where(ch => (! Char.IsLetter(ch))).Distinct().ToArray();
// split into array of words
var words = text.Split(punctuationAndWhiteSpace, StringSplitOptions.RemoveEmptyEntries);
// get the set of distinct words in the text
var distinctWords = words.Distinct();
// build frequency dictionary
Dictionary<string, int> wordCounts = distinctWords.ToDictionary(
wrd => wrd,
wrd => words.Count(w => w == wrd)
);
// sort frequency dictionary by Value
return (sortedLoHi)
? wordCounts.OrderBy(kvp => kvp.Value)
: wordCounts.OrderByDescending(kvp => kvp.Value);
}
You’d call it like this:
You'd call it like this:
var lohi = CountWords("text", true);
var hiloi = CountWords("text", false);
这篇关于如何将配对值从文本框保存到数据库分隔的单词和计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文