将项推送到数组的末尾
本文关键字:数组 | 更新日期: 2023-09-27 18:21:12
不,我不能使用通用集合。事实上,我想做的很简单。在php中,我会做一些类似于的事情
$foo = [];
$foo[] = 1;
我在C#中拥有的是这个
var foo = new int [10];
// yeah that's pretty much it
现在我可以做一些类似foo[foo.length - 1] = 1
的事情,但这显然不起作用。另一个选项是foo[foo.Count(x => x.HasValue)] = 1
以及声明期间可为null的int。但是有可以用一种更简单的方法来解决这个琐碎的任务。
这是家庭作业,我不想向我的老师(可能还有全班同学)解释foo[foo.Count(x => x.HasValue)] = 1
是什么以及它为什么有效等。
最简单的方法是创建一个新的类来保存插入项的索引:
public class PushPopIntArray
{
private int[] _vals = new int[10];
private int _nextIndex = 0;
public void Push(int val)
{
if (_nextIndex >= _vals.Length)
throw new InvalidOperationException("No more values left to push");
_vals[_nextIndex] = val;
_nextIndex++;
}
public int Pop()
{
if (_nextIndex <= 0)
throw new InvalidOperationException("No more values left to pop");
_nextIndex--;
return _vals[_nextIndex];
}
}
您可以添加重载来获取整个数组,也可以根据需要直接对其进行索引。您还可以添加重载或构造函数来创建不同大小的数组等。
在C#中,数组不能动态调整大小。您可以使用Array.Resize(但这可能对性能不利)或替代ArrayList类型。
但必须有一种更简单的方法来解决这个琐碎的任务。
没有。并不是所有的语言都能像其他语言一样简单地完成每件事,这就是为什么集合被发明的原因。C#<>python<>php<>Java语言选择更适合你的语言,但在从一种语言迁移到另一种语言时,并不总是付出同等的努力。
foo[foo.Length]
将无法工作,因为foo。长度索引在数组之外
最后一项位于索引foo.Length - 1
在那之后,数组是一个固定大小的结构,如果你希望它能像php中一样工作,那你就大错特错了
最初我是作为评论写的,但我认为它包含了足够重要的要点,有必要将其作为答案。
你似乎觉得C#是一种尴尬的语言,因为你固执地坚持使用数组,同时要求你应该"把项目推到最后",这一评论证明了这一点:
将项推入数组不是数据结构的全部目的吗?
回答这个问题:不,数组数据结构的目的是有一个连续的预分配内存块,以模仿C(++)中的原始数组结构,您可以轻松地对其进行索引和执行指针运算。
如果您想要一个支持某些操作的数据结构,例如将元素推到末尾,请考虑System.Collections.Generic.List<T>
,或者,如果您坚持避免泛型,则考虑System.Collections.List
。有一些专门化可以指定底层存储结构(如ArrayList
),但通常C#库的全部意义在于,您不想关心这些细节:List<T>
类对其操作有一定的保证(例如,插入是O(n),检索是O(1)——就像数组一样),是否有一个数组或某个链表实际保存数据是无关紧要的,实际上是根据运行时列表的大小和用例动态决定的。
不要试图通过比较PHP数组和C#数组来比较PHP和C#——它们有不同的编程范式,解决其中一个问题的方法不一定会转移到另一个。
为了回答书面问题,我看到了两个选项:
-
使用数组的方式很尴尬。要么创建一个
Nullable<int>
的数组,并接受一些装箱/取消装箱和令人不快的LINQ语句进行插入;或者保留一个额外的计数器(最好与数组一起封装在一个类中)以跟踪最后分配的元素。 -
使用适当的数据结构,并对重要的操作提供适当的保证,例如
List<T>
,它实际上是上面第二个选项的(更好、优化的)内置版本。
我理解后一种选择对你来说是不可行的,因为你的老师施加了限制,但如果你不被允许在另一种语言中使用规范的方式,那么不要惊讶于事情比另一种语文中的规范方式更难。
思考:刚刚想到的一个混合替代方案是使用List进行存储,然后在其上调用.ToArray
。在insert方法中,只将Add
添加到列表中并返回新数组。