【问题标题】:Convert string from Base2 to Base4将字符串从 Base 2 转换为 Base 4
【发布时间】:2014-03-11 23:46:23
【问题描述】:

我希望将文本转换为 base 4 (AGCT),首先将其转换为二进制(我已完成此位),然后将其分成 2 位对。

谁能帮我用 vb.net 语法把它变成代码?

如果(二进制字符串的长度是奇数)在字符串的前面(最左边的位置)添加一个零。创建一个空字符串以添加翻译后的数字。虽然二进制的原始字符串不为空 { 仅将二进制字符串的前两位转换为 base-4 数字,并将此数字添加到新字符串的末尾(最右边)索引。在此之后,从二进制字符串中删除相同的两位数字,如果它不为空,则重复。 }

在这种情况下:

    Dim Base2Convert As String = ""
    For Each C As Char In Result.Text
        Dim s As String = System.Convert.ToString(AscW(C), 2).PadLeft(8, "0")
        Base2Convert &= s
    Next
    Result.Text = Base2Convert 

    Dim Base4Convert As String = ""
    For Each C As Char In Result.Text
        '//<ADD THE STATEMENT ABOVE AS CODE HERE>//
        Base4Convert &= s
    Next
    Result.Text = Base4Convert 

【问题讨论】:

  • 为什么绕道base-2?直接转换成base-4即可。
  • 这样会更容易吗?我认为根据其他人的建议通过 base 2 转换它更简单。
  • 实际上是将第一个循环中的2 更改为4,并且可能会更改填充。您应该尝试理解您正在编写的代码。
  • 当然,这就是我要问的原因。进一步加深我的理解。如果我将 2 更改为 4,程序就会崩溃。我不确定将填充更改为什么。
  • 啊,我忘记了Convert 有多烂。整个 .NET 框架中最没用的类(包括ArraySegment)。我的错。

标签: vb.net string


【解决方案1】:

.NET 不支持转换为非标准基数,例如 4,所以这不起作用:

Dim base4number As String = Convert.ToString(base10number, 4)

From MSDN:

[...] 返回值的基数 [...] 必须是 2、8、10 或 16。

但您可以编写自己的转换函数,或者将现有的从网络上取下来:

Public Function IntToStringFast(value As Integer, baseChars As Char()) As String
  Dim i As Integer = 32
  Dim buffer(i - 1) As Char
  Dim targetBase As Integer = baseChars.Length

  Do
    buffer(System.Threading.Interlocked.Decrement(i)) =
      baseChars(value Mod targetBase)
    value = value \ targetBase
  Loop While value > 0

  Dim result As Char() = New Char(32 - i - 1) {}
  Array.Copy(buffer, i, result, 0, 32 - i)

  Return New String(result)
End Function

使用this answer。使用来自 C# 的 developer fusion 转换 + 小调整。示例:

Dim base2number As String = "11110" 'Decimal 30
Dim base10number As Integer = Convert.ToInt32(base2number, 2)
Dim base4number As String = IntToStringFast(base10number, "0123") 
Console.WriteLine(base4number) 'outputs 132

请注意,您不需要以 2 为基数作为中间值,您可以直接从以 10 为基数进行转换。如果有疑问,它是否工作正常,这里有一个有用的资源:

【讨论】:

  • base10number 这个名字完全错误(而且具有误导性!)。 "30" 是一个以 10 为基数的数字。 base10number 只是数字的值。
  • @KonradRudolph:到底是什么误导? 11110 base 2 是十进制 30,或 30 base 10。这是我在评论中写的。如果您在调试器中将鼠标悬停在base10number 上,它将显示30,它是以10 为底的。那么那里出了什么问题?
  • 你混淆了价值和表现。您在调试器中看到的不是变量的实际内容,而是转换为基数 10 后的 字符串表示形式。如果有的话,整数的实际内部表示形式是基数 2;当然不是以 10 为基数。
  • @KonradRudolph:你有没有试过想象一个没有 字符串表示的以 10 为底的数字?那你为什么要把它们分开呢?
  • 感谢 Neolisk,终于搞定了!但是,自定义函数仅适用于小长度字符串(仅长度
【解决方案2】:

先将数字转换为基数,然后再转换为基数 4 没有多大意义,因为无论如何直接转换为基数 4 是相同的算法。事实上,以 any 为基数的数字表示需要相同的通用算​​法:

Public Shared Function Representation(number As Integer, digits As String) As String
    Dim result = ""
    Dim b = digits.Length

    Do
        result = digits(number Mod b) & result
        number \= b
    Loop While number > 0

    Return result
End Function

现在您可以验证Representation(i, decimal)i.ToString() 的作用相同:

Dim decimalDigits = "0123456789"
For i = 0 To 30 Step 3
    Console.WriteLine("{0}, {1}", i.ToString(), Representation(i, decimalDigits))
Next

值得注意的是,i.ToString()i 转换为十进制基数,因为这是我们人类主要使用的基数。但是十进制并没有什么特别之处,实际上在内部i不是十进制数:它在计算机内存中的表示是二进制的。

要转换为任何其他基,只需将一组不同的digits 传递给该方法。在你的情况下,那就是"ACGT":

Console.WriteLine(Representation(i, "ACGT"))

十六进制也可以:

Console.WriteLine(Representation(i, "0123456789ABCDEF"))

而且,只是重复一遍,因为它是一个非常好的数学属性:任何其他具有至少两个不同数字的基数也是如此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-03
    • 2015-08-09
    • 2012-07-08
    • 2018-01-22
    • 2012-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多