更高效的循环?

3

我正在编写一个简单的结构来模拟字符串数组,但添加了一些实用的操作符和其他我想在字符串中看到的函数。 特别是我现在要处理的方法是 / 操作符。

问题是,它不会像我想要的那样,在末尾添加任何余数。

它应该做的是,取一个字符串数组,例如:{"Hello", "Test1", "Test2", "Goodbye", "More?", "Qwerty"},如果我想除以4,它应该返回 {"Hello","Test1","Test2","Goodbye"},{"More?","Qwerty"},但它没有。

整个类(我希望改进的方法是 / 操作符,但如果你有其他想法,请指出)(我知道几乎没有注释。 对此很抱歉,我没有想到其他人除了我会查看这段代码。):

public struct StringCollection
{
    private String[] value;

    public StringCollection(params String[] s)
    {
        this.value = s;
    }

    public StringCollection(StringCollection current, String ad)
    {
        if (current.value == null) {
            current.value = new String[0] { };
        }
        this.value = new String[current.value.Length+1];
            for (int i=0; i<this.value.Length; i++)
            {
                try {
                    this.value[i] = current[i];
                } catch {
                    break;
                }
            }
            this.value[this.value.Length-1] = ad;
    }
    public StringCollection(StringCollection x, params StringCollection[] y)
    {
        this.value = x.value;
        for (int j=0;j<y.Length;j++)
        {
            for (int i=0;i<y[j].value.Length;i++)
            {
                this += y[j][i];
            }
        }
    }

    public static StringCollection[] operator /(StringCollection x, int y)
    {
        StringCollection[] result = null;
        if (((int)x.value.Length/y) == ((double)x.value.Length)/y)
            result = new StringCollection[y];
        else
            result = new StringCollection[y+1];
        for (int j=0;j<y;j++)
        {
            for (int i=0;i<((int)x.value.Length/y);i++)
            {
                result[j] += x.value[i+(int)((x.value.Length/y)*j)];
            }
        }
        if (((int)x.value.Length/y) != ((double)x.value.Length)/y)
        {
                            // This is the part that isn't working.
            for (int i=0;i<(((int)x.value.Length/y)*result[0].value.Length)-x.value.Length;i++) 
            {
                result[result.Length-1] += x.value[i+((result[0].value.Length)*result.Length-2)];
            }
        }
        return result;
    }
    public String this[int index]
    {
        get {
            return this.value[index];
        }
        set {
            this.value[index] = value;
        }
    }

}

它的作用基本上是将你的数组(单个数组)分成一堆大小相同的数组,然后在末尾添加余数组成一个新的数组。

2
@DJKRAZE,这个问题可能会在代码审查中被关闭,因为他正在询问一个具体的问题。代码审查通常假定代码是可工作的,并询问如何最好地重构。但是这段代码并没有运行,他想知道如何修复它。 - Joel Coehoorn
1
@Winderps:你可能可以减少你展示的代码量。保留StringCollection构造和/操作方法即可。 - IAbstract
2
你的除法逻辑是什么?如何使用字符串来询问“x可以被y整除多少次?”就像整数除法一样。 - kbzombie
2
@Winderps:实际上,在控制流程中吞下异常或使用try-catch是一种不好的做法(仅举一个原因,当捕获异常时,try-catch是一项非常昂贵的操作),因此你应该检查数组的长度并避免这种情况。 - digEmAll
1
你为什么要编写这个StringCollection类?它看起来像是一个非标准的、笨重的、低效的实现,而且已经有了一个相当好用的List<string>。你可以编写一个静态的帮助方法来执行“分组”操作。我不怀疑你需要进行分组操作,但是在我的看法中,重载“/”来表示它是一个可怕的设计决策。将其命名为GetGroupsOf或类似的名称。返回值应该是List<List<string>>类型。 - Jim Mischel
显示剩余14条评论
1个回答

1

首先,你的问题与循环没有真正关系,或者至少只是在你的代码中涉及到了循环。你应该给它取个不同的标题。

其次,你的数组添加/删除操作可以改进;例如,每次将数组大小增加1和减少1,然后重新复制整个数组是一种浪费时间的做法。

现在进入你的问题,你的代码应该基本上像这样:

//Make your return array
int retLen = x.Length / y;      

//Add space for the remainder
if(x.Length % y != 0)
  retLen++;

var ret = new StringCollection[retLen];

//Reusing variables is a good way to save memory, but watch naming conventions as this can be confusing
retLen = 0;

var tempCollection = new StringCollection();

for (int i = 0; i < x.Length; i++)
{
  tempCollection = new StringCollection(tempCollection, x[i]);

  if(i % y == 0 || i == x.Length - 1)
  {
    ret[retLen++] = tempCollection;
    tempCollection = new StringCollection();
    retLen = 0;
  }    
}

return ret;

我真的不喜欢这个结构中没有添加函数,以便我们清楚明白。当涉及创建所有这些新对象的CPU时间时,tempCollection = new StringCollection(tempCollection, x[i]);非常糟糕。我很确定你需要调整它以确保所有项目都被正确输入,但那是第一次尝试,所以...算了。因为没有人实际上会回答你,所以我花了点时间。

编辑:发现一个错误,在添加到ret时忘记将retLen设置回0。


谢谢你!哇,和你的代码相比,我的看起来像意大利面条一样。从现在开始我会使用你的代码了。 :D - Winderps

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接