洗牌字符串数组在vb.net [英] Shuffling an array of strings in vb.net

查看:150
本文介绍了洗牌字符串数组在vb.net的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发在vb.net网页,将产生一些选择题给用​​户。我需要洗牌那些已放入数组中的四个答案。让我们假设我有以下数组:

I am developing a webpage in vb.net that will generate a number of multiple choice questions to the user. I need to shuffle the four answers which are already put in an array. Lets assume that I have to following array:

array = {"Correct", "Wrong1", "Wrong2", "Wrong3"}

我试着用下面的方法:

I tried to use the following method:

Public Shared Function Shuffle(ByVal items() As String) As Array
        Dim max_index As Integer = items.Length - 1
        Dim rnd As New Random(DateTime.Now.Millisecond)
        For i As Integer = 0 To max_index
            ' Pick an item for position i.
            Randomize()
            Dim j As Integer = rnd.Next(i, max_index)
            ' Swap them.
            Dim temp As String = items(i)
            items(i) = items(j)
            items(j) = temp
        Next i
        Return items
    End Function

该功能正在工作真的很好,但我的问题是,如果我有四个问题,答案将被洗牌的每个问题,但正确的答案会像一个位置:

The function is working really fine, but my problem is that if I have four questions, the answers will be shuffled for each question but the correct answer will be in one position like:

    array = {"Wrong1", "Correct", "Wrong2", "Wrong3"}
    array = {"Wrong2", "Correct", "Wrong3", "Wrong1"}
    array = {"Wrong3", "Correct", "Wrong1", "Wrong2"}
    array = {"Wrong1", "Correct", "Wrong3", "Wrong2"}

我需要的是正确的答案,从一个问题改变其位置到另一个位置。
你的帮助是AP preciated。

What I need is the correct answer to change its location from one question to another. Your help is appreciated.

推荐答案

有与你的洗牌方法,并使用随机

There are several issues with your your Shuffle method and use of Random.


  1. 随机化是与旧的使用,传统的VB 的Rnd 功能。这对闪亮的新NET没有影响随机类。

  2. 很少有需要提供自定义的种子;其实这可以对你的工作。

  3. 创建有一个随机整个应用程序使用,而每次洗牌的时间比(或点击的东西)。而在一个循环永远不会创建它们 - 这几乎保证重复的数字

  1. Randomize is for use with the old, legacy VB Rnd function. It has no impact on the shiny new NET Random class.
  2. There is rarely a need to provide a custom seed; in fact this can work against you.
  3. Create one Random for the entire app to use rather than each time you shuffle (or click something). And never create them in a loop - this almost guarantees repeated numbers.

最大参数 Random.Next(最小值,最大值)独家的,所以你的范围实际上是1元小于它应该是。

The max argument to Random.Next(min, max) is exclusive, so your range is actually 1 element smaller than it should be.


  • 一般来说,费雪耶茨洗牌是一个到位洗牌(),使得它非常有效的(而不是返回一个新的集合)

  • 这是重要的循环向后的直通列表或数组。 1

  • Generally the NET version of the Fisher-Yates Shuffle is an in place shuffle (Sub) making it very efficient (rather than returning a new collection)
  • It is important to loops backwards thru the list or array.1

标准费雪耶茨洗牌:

' form/class level var
Private rnd As New Random()

Public Sub Shuffle(items As String())
    Dim j As Int32
    Dim temp As String

    For n As Int32 = items.Length - 1 To 0 Step -1
        j = rnd.Next(0, n + 1)
        ' Swap them.
        temp = items(n)
        items(n) = items(j)
        items(j) = temp
    Next i
End Sub

从4洗牌同一起跑线阵列的输出:

Output from 4 shuffles of the same starting array:

Shuffle #1    Wrong3   Correct  Wrong2   Wrong1   
Shuffle #2    Correct  Wrong2   Wrong1    Wrong3   
Shuffle #3    Wrong2   Correct  Wrong3    Wrong1   
Shuffle #4    Correct  Wrong1   Wrong2    Wrong3   
Shuffle #5    Correct  Wrong1   Wrong3    Wrong2   

变体形式

而不是全局随机生成器,你可以通过它(作为一个扩展的方法有用):

Variations

Rather than a global Random generator, you can pass it (useful as an extension method):

Public Sub Shuffle(items As String(), RNG As Random)

洗牌的泛型方法的许多的类型:

Generic method for shuffling many types:

' Generic shuffle for basic type arrays
Public Sub Shuffle(Of T)(items As T(), rng As Random)
    Dim temp As T
    Dim j As Int32

    For i As Int32 = items.Count - 1 To 0 Step -1
        ' Pick an item for position i.
        j = rng.Next(i + 1)
        ' Swap 
        temp = items(i)
        items(i) = items(j)
        items(j) = temp
    Next i
End Sub

例如:

Shuffle(intArray, myRnd)
Shuffle(strArray, myRnd)
Shuffle(colors, myRnd)
Shuffle(myButtons, myRnd)

简单的重新排序

最后,简单的东西,你可能只用一个扩展方法重新排序一次,简单,通常-足够好版本:

Finally, for something simple where you might only reorder them once, a simple and usually-good-enough version using an extension method:

Dim ShuffledItems = myItems.OrderBy(Function() rnd.Next).ToArray()

这少code和容易冲关,但是的的效率较低。

This has less code and is easy to dash off, but is much less efficient.

1 要循环的原因是向后限制每个数组元素为 有一个掉。一旦X移动到在最后一步的项目(J),该位置是从考虑删除,因为 rnd.Next(0,N + 1)只会挑选的最多的最后一个元素/循环索引。许多实现得到这个错误的。

1 The reason that you want to loop backwards is to limit each array element to one swap. Once "X" is moved to items(j) in the last step, that position is removed from consideration because rnd.Next(0, n + 1) will only pick up to the last element/loop index. Many implementations get this wrong.

这篇关于洗牌字符串数组在vb.net的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆