我正在尝试将一个字符串添加到一个数组中,我做了很多研究,并提出了两个选项,但都没有工作,我得到一个弹出窗口,细节使它听起来像我的阵列是两个方法都在我的addSpam函数中。关于如何修复这两种方法的任何想法?
namespace HW8_DR
{
class Tester : Spam_Scanner
{
private string[] spam = {"$$$", "Affordable", "Bargain", "Beneficiary", "Best price", "Big bucks",
"Cash", "Cash bonus", "Cashcashcash", "Cents on the dollar", "Cheap", "Check",
"Claims", "Collect", "Compare rates", "Cost", "Credit", "Credit bureaus",
"Discount", "Earn", "Easy terms", "F r e e", "Fast cash", "For just $XXX",
"Hidden assets", "hidden charges", "Income", "Incredible deal", "Insurance",
"Investment", "Loans", "Lowest price", "Million dollars", "Money", "Money back",
"Mortgage", "Mortgage rates", "No cost", "No fees", "One hundred percent free",
"Only $", "Pennies a day", "Price", "Profits", "Pure profit", "Quote", "Refinance",
"Save $", "Save big money", "Save up to", "Serious cash", "Subject to credit",
"They keep your money – no refund!", "Unsecured credit", "Unsecured debt",
"US dollars", "Why pay more?"};
public static double countSpam = 0;
public static double wordCount = 0;
public static string posSpam = "";
public void tester(string email)
{
for(int i = 0; i < spam.Length-1; i++)
if(email.Contains(spam[i]))
{
countSpam++;
posSpam = string.Concat(posSpam, spam[i], "\r\n\r\n");
}
wordCount = email.Split(' ').Length;
}
public void addSpam(string spamFlag)
{
//attempt 1 to add string to spam array
Array.Resize(ref spam, spam.Length + 1);
spam[spam.Length] = spamFlag;
//attempt 2 to add string to spam array
string[] temp = new string[spam.Length + 1];
Array.Copy(spam, temp, spam.Length);
temp.SetValue(spamFlag, spam.Length);
Array.Copy(temp, spam, temp.Length);
}
}
}`
答案 0 :(得分:4)
简单的解决方案:不要使用阵列! List<T>
更适合这种情况。
using System.Collections.Generic;
...
private List<string> spam = {"$$$", "Affordable", "Bargain", "Beneficiary", ... }
...
public void addSpam(string spamFlag)
{
spam.Add(spamFlag);
}
答案 1 :(得分:2)
DLeh的答案是最好的 - 这是List<T>
的用途,因此这是您的解决方案。
但事情失败的原因是您尝试访问的索引高于数组的最大索引。最高索引总是小于长度,因为数组是从零开始的。
int[] arr = new[] { 1, 2, 3 };
Console.WriteLine(arr.Length); // 3
Console.WriteLine(arr[0]); // 1
Console.WriteLine(arr[1]); // 2
Console.WriteLine(arr[2]); // 3
Console.WriteLine(arr[3]); // Exception
要访问数组中的最后一项,您需要使用:
var lastItem = arr[arr.Length - 1];
// or
var lastItem = arr[arr.GetUpperBound(0)];
答案 2 :(得分:0)
Array.Resize(ref spam, spam.Length + 1);
spam[spam.Length] = spamFlag;
在这里,您尝试写入58元素零索引数组的索引58
(重新调整后的spam.Length
);也就是说,它从0
变为57
。
您应该使用:
Array.Resize(ref spam, spam.Length + 1);
spam[spam.Length - 1] = spamFlag;
那就是说,你应该真的使用List<string>
。除此之外,它还会调整批量使用的内部数组的大小,而不是每个Add()
,这样可以提高效率,并且更容易。
如果您出于某种原因确实需要数组,请在大多数工作中使用List<string>
,然后在结尾处调用ToArray()
。
答案 3 :(得分:0)
虽然DLeh提出了关于如何更好地使用动态增长的List的合理观点,而Joe的回答提供了很好的解释,但我想补充一些其他内容。
首先,要回答您的问题,要修正这两种方法,您可能想要尝试spam[spam.Length-1] = spamFlag
而不是spam[spam.Length] = spamFlag
。因为索引从0开始,并且绑定中的最后一个索引因此长度为-1(正如Joe指出的那样)
如果任何一个数组太短,则第二次尝试将无效,因为抛出异常。见dotnetPerl link on the explanation。基本上不建议使用Array.Copy,因为您必须确保类型和长度也一样。
要详细说明Array.Resize()
,应该注意的是,它实际上是一个误称,其中C#实际上没有调整数组。相反,它创建一个新数组并复制内容。除非抛出异常,否则它总是这样做,因此从性能的角度来看,这是不鼓励的。 (你可以有一个变量来跟踪数组的完整程度,并且总是将它增加一倍,这样就可以避免总是创建一个新数组。)
这也用在哈希表中,如果某个存储桶已满,我们会增加它并将所有内容重新打包(它是一个非常快速的查找表/数据结构)。
阅读此 DotNetPerl tutorial on Array Resize
然而,很多时候List更好,但当然可能有一个你不想/无法使用的原因。我知道有几个类明确告诉我们不要使用内置的数据结构来学习数组的工作原理。