我一直在尝试使用for循环来检查数组中是否存在元素。我似乎无法弄清楚如何做到这一点,因为在for循环内声明的所有变量都无法从其范围之外访问。我该如何正确地做到这一点?
var array = new[] { 3, 4, 2, 6, 3 };
var value = 2;
bool isContained;
for(var i = 0; i < array.Length; i++)
isContained = (value == array[i]);
if(isContained)
Console.WriteLine("The value is in the array");
else
Console.WriteLine("The value is not in the array");
答案 0 :(得分:8)
除了这样的事实之外,你的代码甚至不能编译,因为isContained
可能永远不会被初始化,问题是你会在{{一遍又一遍地覆盖isContained
。 1}}循环:
for
基本上,当且仅当您找到了正确的值时才需要设置它。所以基本的工作版本是:
bool isContained;
for(var i = 0; i < array.Length; i++)
isContained = (value == array[i]);
显然,一旦遇到匹配,迭代数组的其余部分是没有意义的。因此,这稍微好一些:
bool isContained = false;
for(var i = 0; i < array.Length; i++)
{
if (value == array[i]) isContained = true;
}
这是理解这个概念的好方法。然而,正如有人在评论中指出的那样,存在一种更为先进的解决方案,即“一线”:
bool isContained = false;
for(var i = 0; i < array.Length; i++)
{
if (value == array[i])
{
isContained = true;
break;
}
}
答案 1 :(得分:2)
问题是您的isContained
值会在每次迭代中被覆盖。您的代码应按如下方式编写:
Boolean isContained = false;
for (Int32 i = 0; i < array.Length; ++i)
{
if (value == array[i])
{
isContained = true;
break; // no need further processing, you found it
}
}
旁注...为什么不使用Enumerable.Contains()?
Int32[] array = new Int32[] { 3, 4, 2, 6, 3 };
Int32 value = 2;
if (array.Contains(value))
Console.WriteLine("The value '{0}' has been found in the array!", value);
或LINQ
解决方案如下:
Int32[] array = new Int32[] { 3, 4, 2, 6, 3 };
Int32 value = 2;
if (array.Any(x => x == value))
Console.WriteLine("The value '{0}' has been found in the array!", value);
答案 2 :(得分:1)
尝试从循环内部返回。
for(var i = 0; i < array.Length; i++)
{
if(value == array[i])
{
Console.WriteLine("The value is in the array");
return;
}
}
Console.WriteLine("The value is not in the array");
答案 3 :(得分:1)
您的代码有三个问题。
首先,编译器无法检测到肯定会分配isContained
。考虑数组是否为空;然后永远不会设置isContained
,使用尚未设置的值是不合法的。编译器必须是相对本地的,以确定是否已经设置了一个值(如果它更聪明,我们最终会遇到很难解决为什么允许它们的情况),所以这是一个禁忌。
当然如果确实发生了数组是空的,我们应该得到一个结果,应该是false
。
我们可以通过将值设置为false
:
var array = new[] { 3, 4, 2, 6, 3 };
var value = 2;
bool isContained = false;
for (var i = 0; i < array.Length; i++)
isContained = (value == array[i]);
if (isContained)
Console.WriteLine("The value is in the array");
else
Console.WriteLine("The value is not in the array");
它给了我们错误的答案,揭示了第三个问题;因为isContained
一直在写它只告诉我们最后的答案。解决此问题的一种方法是使用|=
,以便将false设置为true,但不能为false:
var array = new[] { 3, 4, 2, 6, 3 };
var value = 2;
bool isContained = false;
for (var i = 0; i < array.Length; i++)
isContained |= (value == array[i]);
if (isContained)
Console.WriteLine("The value is in the array");
else
Console.WriteLine("The value is not in the array");
这有效,但很浪费。一旦我们知道数值在数组中,如果我们查看0,2或10亿个值并不重要;答案是真的。所以我们应该停止寻找:
var array = new[] { 3, 4, 2, 6, 3 };
var value = 2;
bool isContained = false;
for (var i = 0; i < array.Length; i++)
{
if (value == array[i])
{
isContained = true;
break;
}
}
if (isContained)
Console.WriteLine("The value is in the array");
else
Console.WriteLine("The value is not in the array");
这可以更快地为我们提供正确的答案。
顺便提一下,一个值得了解的更简单的版本是使用Contains()
来解决这些问题:
if (array.Contains(value))
Console.WriteLine("The value is in the array");
else
Console.WriteLine("The value is not in the array");
或更一般地Any()
可以询问有关集合的更灵活的问题:
if (array.Any(x => x == value))
Console.WriteLine("The value is in the array");
else
Console.WriteLine("The value is not in the array");
能够自己循环,但仍然是一个重要的技术知识。它也是最快的,尽管差别很小,只有在紧密循环中才有意义:继续学习for
循环,直到你对它们充满信心,然后使用更简洁和不言自明的Contains
或适用时Any
,但性能关键点除外。
答案 4 :(得分:1)
虽然你要求for循环,但无限时间可能会更好。就个人而言,我发现while循环更具表现力和表达能力。这个概念或者前提是当循环迭代时,一旦找到匹配就会停止。
在我看来,for循环的功能几乎完全相同,但在执行此循环时,显式操作将随之而来。如果for循环很快,遍历一个集合,那么就会有一个动作。
大多以短语或快速浏览的方式,您很快就会有意图。
int index = 0;
int value = 9;
bool valid = false;
while(collection.length != index)
{
if(value == collection[index])
{
valid = true;
break;
}
index++
}
你也可以通过更具表现力的Linq实现这一目标。
int value = 9;
var valid = collection.Any(item => item == value);
就我个人而言,我发现any和while更具表现力和自我记录的用例。
答案 5 :(得分:0)
你是什么意思?您的代码有问题,但没有一个涉及无法访问我似乎无法弄清楚如何执行此操作,因为在for循环内声明的所有变量都无法从其范围之外访问
for
循环内声明的变量。
您发布的代码应该接近成功编译。它确实有几个问题:
isContained
。这将导致编译器发出CS0165,“使用未分配的局部变量”。使用初始化声明变量:bool isContained = false;
。isContained
,所以最后得到的只是数组中的 last 元素是否是您正在寻找的。请尝试isContained |= (value == array[i]);
,或类似:if (value == array[i])
{
isContained = true;
break;
}
这比仅使用|=
运算符更冗长,但它确实会提前终止循环。
当然,如果你只是想获得价值,并且不想学习如何编写这样的循环,你可以使用内置的Enumerable.Contains()
方法:
bool isContained = array.Contains(value);
答案 6 :(得分:0)
我知道这已经被解决了......但是
这里有很多方法可以实现你想要的,它的好处 了解所有这些变体,因为它们将成为面包和黄油 您将来设计的几乎所有算法
鉴于这些变量
var array = new[] { 3, 4, 2, 6, 3 };
var value = 2;
var isFound = false;
您可以使用for
循环
for (var i = 0; i < array.Length; i++) // loop to the end of the array
{
if (array[i] == value) // comparison
{
isFound = true; // we found
break; // We can exit the loop early
}
}
// Write our results
Console.WriteLine($"Found = {isFound}");
您可以使用foreach
循环
foreach (var element in array) // loop to the end of the array
{
if (element == value) // comparison
{
isFound = true; // we found
break; // We can exit the loop early
}
}
// Write our results
Console.WriteLine($"Found = {isFound}");
您可以使用while
循环
var index = 0;
while (index < array.Length) // loop to the end of the array
{
if (array[index] == value) // comparison
{
isFound = true; // we found
break; // We can exit the loop early
}
index++; //++ is just a fancy way of saying Add one now before comparison
}
// Write our results
Console.WriteLine($"Found = {isFound}");
您可以使用do while
循环
var index = 0;
do // loop to the end of the array
{
if (array[index] == value) // comparison
{
isFound = true; // we found
break; // We can exit the loop early
}
} while (++index < array.Length);// ++ is just a fancy way of saying Add one now before comparison
您可以使用Linq
Any
// a fancy way of saying, does any element in the array match the value
isFound = array.Any(element => element == value);
// Write our results
Console.WriteLine($"Found = {isFound}");
您可以使用Linq
Contains
// a fancy way of saying does the array contain your value
isFound = array.Contains(value);
// Write our results
Console.WriteLine($"Found = {isFound}");
其他资源
答案 7 :(得分:-1)
您可以轻松使用List
代替int[]
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
List<int> list = new List<int>(){ 2, 3, 7 };
Console.WriteLine("List size: {0}", list.Count);
Console.WriteLine("List has '1': {0}", list.Contains(1));
Console.WriteLine("List has '2': {0}", list.Contains(2));
Console.WriteLine("List has '3': {0}", list.Contains(3));
}
}