将基本10号转换为.NET中的任何基础的最快方法?
-
06-09-2019 - |
题
我和旧的(ish)C#方法我写了一个数字并将其转换为任何基础:
string ConvertToBase(int number, char[] baseChars);
并不是那么超级迅速和整洁。是否有一种在.NET中实现这一目标的好方法?
我正在寻找可以让我使用的东西 任何 基础具有任意字符串的字符串。
这仅允许基地16、10、8和2:
Convert.ToString(1, x);
我想用它来实现巨大的基础,利用数字,所有较低的案例和所有上层案例字母。像 这个线程, ,但对于C#而不是JavaScript。
有人知道在C#中做到这一点的好方法吗?
解决方案
Convert.ToString
可用于在指定基础中将数字转换为其等效字符串表示。
例子:
string binary = Convert.ToString(5, 2); // convert 5 to its binary representation
Console.WriteLine(binary); // prints 101
但是,正如评论所指出的那样, Convert.ToString
仅支持以下限制(但通常足够的基础):2、8、10或16。
更新(满足转换为任何基础的要求):
我不知道BCL中能够将数字转换为任何基础的任何方法,因此您必须编写自己的小型公用事业功能。一个简单的样本看起来像这样(请注意,可以通过替换字符串串联来更快地制作此样本):
class Program
{
static void Main(string[] args)
{
// convert to binary
string binary = IntToString(42, new char[] { '0', '1' });
// convert to hexadecimal
string hex = IntToString(42,
new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'});
// convert to hexavigesimal (base 26, A-Z)
string hexavigesimal = IntToString(42,
Enumerable.Range('A', 26).Select(x => (char)x).ToArray());
// convert to sexagesimal
string xx = IntToString(42,
new char[] { '0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x'});
}
public static string IntToString(int value, char[] baseChars)
{
string result = string.Empty;
int targetBase = baseChars.Length;
do
{
result = baseChars[value % targetBase] + result;
value = value / targetBase;
}
while (value > 0);
return result;
}
/// <summary>
/// An optimized method using an array as buffer instead of
/// string concatenation. This is faster for return values having
/// a length > 1.
/// </summary>
public static string IntToStringFast(int value, char[] baseChars)
{
// 32 is the worst cast buffer size for base 2 and int.MaxValue
int i = 32;
char[] buffer = new char[i];
int targetBase= baseChars.Length;
do
{
buffer[--i] = baseChars[value % targetBase];
value = value / targetBase;
}
while (value > 0);
char[] result = new char[32 - i];
Array.Copy(buffer, i, result, 0, 32 - i);
return new string(result);
}
}
更新2(绩效改进)
使用数组缓冲区而不是字符串串联来构建结果字符串,尤其是在大量上进行性能改进(请参阅方法 IntToStringFast
)。在最好的情况下(即最长的输入),此方法大约要快三倍。但是,对于1位数字(即目标基库中的1位), IntToString
会更快。
其他提示
我最近写了这一点. 。我的实现在计算过程中不使用任何字符串操作,这使得 非常快. 。支持将基数从2到36的任何数字系统转换为:
/// <summary>
/// Converts the given decimal number to the numeral system with the
/// specified radix (in the range [2, 36]).
/// </summary>
/// <param name="decimalNumber">The number to convert.</param>
/// <param name="radix">The radix of the destination numeral system (in the range [2, 36]).</param>
/// <returns></returns>
public static string DecimalToArbitrarySystem(long decimalNumber, int radix)
{
const int BitsInLong = 64;
const string Digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (radix < 2 || radix > Digits.Length)
throw new ArgumentException("The radix must be >= 2 and <= " + Digits.Length.ToString());
if (decimalNumber == 0)
return "0";
int index = BitsInLong - 1;
long currentNumber = Math.Abs(decimalNumber);
char[] charArray = new char[BitsInLong];
while (currentNumber != 0)
{
int remainder = (int)(currentNumber % radix);
charArray[index--] = Digits[remainder];
currentNumber = currentNumber / radix;
}
string result = new String(charArray, index + 1, BitsInLong - index - 1);
if (decimalNumber < 0)
{
result = "-" + result;
}
return result;
}
我还实施了快速逆功能,以防万一其他人也需要它:任意到十进制数字系统.
快速地 ”从“ 和 ”至“ 方法
我参加聚会迟到了,但是我更加复杂了以前的答案,并改善了他们。我认为这两种方法比到目前为止发布的任何其他方法都要快。我能够在一台核心机器中将1,000,000个数字从400毫秒以下的36中转换为36个。
下面的示例是 基础62. 。更改 BaseChars
阵列要转换为其他碱基。
private static readonly char[] BaseChars =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".ToCharArray();
private static readonly Dictionary<char, int> CharValues = BaseChars
.Select((c,i)=>new {Char=c, Index=i})
.ToDictionary(c=>c.Char,c=>c.Index);
public static string LongToBase(long value)
{
long targetBase = BaseChars.Length;
// Determine exact number of characters to use.
char[] buffer = new char[Math.Max(
(int) Math.Ceiling(Math.Log(value + 1, targetBase)), 1)];
var i = buffer.Length;
do
{
buffer[--i] = BaseChars[value % targetBase];
value = value / targetBase;
}
while (value > 0);
return new string(buffer, i, buffer.Length - i);
}
public static long BaseToLong(string number)
{
char[] chrs = number.ToCharArray();
int m = chrs.Length - 1;
int n = BaseChars.Length, x;
long result = 0;
for (int i = 0; i < chrs.Length; i++)
{
x = CharValues[ chrs[i] ];
result += x * (long)Math.Pow(n, m--);
}
return result;
}
编辑(2018-07-12)
修复以解决@AdrianBotor(请参阅注释)发现46655转换为基础36的角案例。这是由一个小的浮点错误计算引起的 Math.Log(46656, 36)
这恰好是3个,但是.NET返回 3 + 4.44e-16
, ,这会在输出缓冲区中引起额外的字符。
一个人还可以使用被接受的版本的略微修改版本,并根据其需求调整基本字符字符串:
public static string Int32ToString(int value, int toBase)
{
string result = string.Empty;
do
{
result = "0123456789ABCDEF"[value % toBase] + result;
value /= toBase;
}
while (value > 0);
return result;
}
在这个聚会上,我最近为一个工作的助手班写了一个派对。它旨在将短字符串转换为数字并再次返回(一个简单的 完美的哈希 函数),但是,它还将在任意基础之间执行数字转换。这 Base10ToString
方法实施回答了最初发布的问题。
这 shouldSupportRoundTripping
需要传递给类构造函数的标志,以防止转换为基础10并再次返回的数字字符串的丢失(鉴于我的要求,至关重要!)。在大多数情况下,从数字字符串中引导0的损失可能不是问题。
无论如何,这是代码:
using System;
using System.Collections.Generic;
using System.Linq;
namespace StackOverflow
{
/// <summary>
/// Contains methods used to convert numbers between base-10 and another numbering system.
/// </summary>
/// <remarks>
/// <para>
/// This conversion class makes use of a set of characters that represent the digits used by the target
/// numbering system. For example, binary would use the digits 0 and 1, whereas hex would use the digits
/// 0 through 9 plus A through F. The digits do not have to be numerals.
/// </para>
/// <para>
/// The first digit in the sequence has special significance. If the number passed to the
/// <see cref="StringToBase10"/> method has leading digits that match the first digit, then those leading
/// digits will effectively be 'lost' during conversion. Much of the time this won't matter. For example,
/// "0F" hex will be converted to 15 decimal, but when converted back to hex it will become simply "F",
/// losing the leading "0". However, if the set of digits was A through Z, and the number "ABC" was
/// converted to base-10 and back again, then the leading "A" would be lost. The <see cref="System.Boolean"/>
/// flag passed to the constructor allows 'round-tripping' behaviour to be supported, which will prevent
/// leading digits from being lost during conversion.
/// </para>
/// <para>
/// Note that numeric overflow is probable when using longer strings and larger digit sets.
/// </para>
/// </remarks>
public class Base10Converter
{
const char NullDigit = '\0';
public Base10Converter(string digits, bool shouldSupportRoundTripping = false)
: this(digits.ToCharArray(), shouldSupportRoundTripping)
{
}
public Base10Converter(IEnumerable<char> digits, bool shouldSupportRoundTripping = false)
{
if (digits == null)
{
throw new ArgumentNullException("digits");
}
if (digits.Count() == 0)
{
throw new ArgumentException(
message: "The sequence is empty.",
paramName: "digits"
);
}
if (!digits.Distinct().SequenceEqual(digits))
{
throw new ArgumentException(
message: "There are duplicate characters in the sequence.",
paramName: "digits"
);
}
if (shouldSupportRoundTripping)
{
digits = (new[] { NullDigit }).Concat(digits);
}
_digitToIndexMap =
digits
.Select((digit, index) => new { digit, index })
.ToDictionary(keySelector: x => x.digit, elementSelector: x => x.index);
_radix = _digitToIndexMap.Count;
_indexToDigitMap =
_digitToIndexMap
.ToDictionary(keySelector: x => x.Value, elementSelector: x => x.Key);
}
readonly Dictionary<char, int> _digitToIndexMap;
readonly Dictionary<int, char> _indexToDigitMap;
readonly int _radix;
public long StringToBase10(string number)
{
Func<char, int, long> selector =
(c, i) =>
{
int power = number.Length - i - 1;
int digitIndex;
if (!_digitToIndexMap.TryGetValue(c, out digitIndex))
{
throw new ArgumentException(
message: String.Format("Number contains an invalid digit '{0}' at position {1}.", c, i),
paramName: "number"
);
}
return Convert.ToInt64(digitIndex * Math.Pow(_radix, power));
};
return number.Select(selector).Sum();
}
public string Base10ToString(long number)
{
if (number < 0)
{
throw new ArgumentOutOfRangeException(
message: "Value cannot be negative.",
paramName: "number"
);
}
string text = string.Empty;
long remainder;
do
{
number = Math.DivRem(number, _radix, out remainder);
char digit;
if (!_indexToDigitMap.TryGetValue((int) remainder, out digit) || digit == NullDigit)
{
throw new ArgumentException(
message: "Value cannot be converted given the set of digits used by this converter.",
paramName: "number"
);
}
text = digit + text;
}
while (number > 0);
return text;
}
}
}
这也可以将其子分类用于得出自定义数字转换器:
namespace StackOverflow
{
public sealed class BinaryNumberConverter : Base10Converter
{
public BinaryNumberConverter()
: base(digits: "01", shouldSupportRoundTripping: false)
{
}
}
public sealed class HexNumberConverter : Base10Converter
{
public HexNumberConverter()
: base(digits: "0123456789ABCDEF", shouldSupportRoundTripping: false)
{
}
}
}
并且代码将像这样使用:
using System.Diagnostics;
namespace StackOverflow
{
class Program
{
static void Main(string[] args)
{
{
var converter = new Base10Converter(
digits: "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz",
shouldSupportRoundTripping: true
);
long number = converter.StringToBase10("Atoz");
string text = converter.Base10ToString(number);
Debug.Assert(text == "Atoz");
}
{
var converter = new HexNumberConverter();
string text = converter.Base10ToString(255);
long number = converter.StringToBase10(text);
Debug.Assert(number == 255);
}
}
}
}
这堂课可以从 这个论坛帖子 帮你?
public class BaseConverter {
public static string ToBase(string number, int start_base, int target_base) {
int base10 = this.ToBase10(number, start_base);
string rtn = this.FromBase10(base10, target_base);
return rtn;
}
public static int ToBase10(string number, int start_base) {
if (start_base < 2 || start_base > 36) return 0;
if (start_base == 10) return Convert.ToInt32(number);
char[] chrs = number.ToCharArray();
int m = chrs.Length - 1;
int n = start_base;
int x;
int rtn = 0;
foreach(char c in chrs) {
if (char.IsNumber(c))
x = int.Parse(c.ToString());
else
x = Convert.ToInt32(c) - 55;
rtn += x * (Convert.ToInt32(Math.Pow(n, m)));
m--;
}
return rtn;
}
public static string FromBase10(int number, int target_base) {
if (target_base < 2 || target_base > 36) return "";
if (target_base == 10) return number.ToString();
int n = target_base;
int q = number;
int r;
string rtn = "";
while (q >= n) {
r = q % n;
q = q / n;
if (r < 10)
rtn = r.ToString() + rtn;
else
rtn = Convert.ToChar(r + 55).ToString() + rtn;
}
if (q < 10)
rtn = q.ToString() + rtn;
else
rtn = Convert.ToChar(q + 55).ToString() + rtn;
return rtn;
}
}
完全未经测试...让我知道它是否有效! (如果论坛帖子消失或其他内容,则将其复制贴上...)
我也正在寻找一种快速的方法,将小数号码转换为[2..36]范围内的另一个基数,因此我开发了以下代码。它易于遵循,并使用StringBuilder对象作为角色缓冲区的代理,我们可以按字符索引字符。与替代方案相比,该代码似乎非常快,并且比角色数组中的单个字符快得多。
为了自己使用,您可能更喜欢:1/返回空白字符串而不是抛出异常。 2/删除radix检查以使该方法运行更快3/用32'0初始化StringBuilder对象并删除线结果。这将导致字符串与领先的零一起返回并进一步提高速度。 4/使StringBuilder对象成为类中的静态字段,因此,无论Decimaltobase方法被称为StringBuilder对象多少次,仅一次初始化。如果您执行此更改,上面的3将不再起作用。
我希望有人发现这个有用:)
原子帕多克斯
static string DecimalToBase(int number, int radix)
{
// Check that the radix is between 2 and 36 inclusive
if ( radix < 2 || radix > 36 )
throw new ArgumentException("ConvertToBase(int number, int radix) - Radix must be between 2 and 36.");
// Create a buffer large enough to hold the largest int value represented in binary digits
StringBuilder result = new StringBuilder(" "); // 32 spaces
// The base conversion calculates the digits in reverse order so use
// an index to point to the last unused space in our buffer
int i = 32;
// Convert the number to the new base
do
{
int remainder = number % radix;
number = number / radix;
if(remainder <= 9)
result[--i] = (char)(remainder + '0'); // Converts [0..9] to ASCII ['0'..'9']
else
result[--i] = (char)(remainder + '7'); // Converts [10..36] to ASCII ['A'..'Z']
} while ( number > 0 );
// Remove the unwanted padding from the front of our buffer and return the result
// Note i points to the last unused character in our buffer
result.Remove( 0, i );
return (result.ToString());
}
我正在使用它将GUID存储为较短的字符串(但仅限于使用106个字符)。如果有人感兴趣,这里是我用于将字符串解码回数值值的代码(在这种情况下,我使用2个ulongs来进行GUID值,而不是编码INT128(因为我在3.5不是4.0中)。对于Clarity Code来说,是一个带有106个唯一字符的字符串const。convertlongstobytes非常不引人注目。
private static Guid B106ToGuid(string pStr)
{
try
{
ulong tMutl = 1, tL1 = 0, tL2 = 0, targetBase = (ulong)CODE.Length;
for (int i = 0; i < pStr.Length / 2; i++)
{
tL1 += (ulong)CODE.IndexOf(pStr[i]) * tMutl;
tL2 += (ulong)CODE.IndexOf(pStr[pStr.Length / 2 + i]) * tMutl;
tMutl *= targetBase;
}
return new Guid(ConvertLongsToBytes(tL1, tL2));
}
catch (Exception ex)
{
throw new Exception("B106ToGuid failed to convert string to Guid", ex);
}
}
我也有类似的需求,除了我还需要在“数字”上进行数学。我在这里接受了一些建议,并创建了一个可以做所有这些有趣的事情的课程。它允许使用任何Unicode字符来表示数字,并且也可以与小数组合使用。
该课程非常易于使用。只需创建一个数字作为 New BaseNumber
, ,设置一些属性,然后关闭。例程会自动考虑在基本10和基础X之间切换,并且您设置的值保留在您设置的基础中,因此不会丢失准确性(直到转换为止,但是即使这样,精确损失也应该很小,因为此常规用途 Double
和 Long
任何可能的地方)。
我无法按照此例程的速度命令。它可能很慢,所以我不确定它是否适合提出问题的人的需求,但可以肯定的是灵活,因此希望其他人可以使用它。
对于可能需要此代码来计算Excel中的下一列的任何其他人,我将包括我使用该类的循环代码。
Public Class BaseNumber
Private _CharacterArray As List(Of Char)
Private _BaseXNumber As String
Private _Base10Number As Double?
Private NumberBaseLow As Integer
Private NumberBaseHigh As Integer
Private DecimalSeparator As Char = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator
Private GroupSeparator As Char = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator
Public Sub UseCapsLetters()
'http://unicodelookup.com
TrySetBaseSet(65, 90)
End Sub
Public Function GetCharacterArray() As List(Of Char)
Return _CharacterArray
End Function
Public Sub SetCharacterArray(CharacterArray As String)
_CharacterArray = New List(Of Char)
_CharacterArray.AddRange(CharacterArray.ToList)
TrySetBaseSet(_CharacterArray)
End Sub
Public Sub SetCharacterArray(CharacterArray As List(Of Char))
_CharacterArray = CharacterArray
TrySetBaseSet(_CharacterArray)
End Sub
Public Sub SetNumber(Value As String)
_BaseXNumber = Value
_Base10Number = Nothing
End Sub
Public Sub SetNumber(Value As Double)
_Base10Number = Value
_BaseXNumber = Nothing
End Sub
Public Function GetBaseXNumber() As String
If _BaseXNumber IsNot Nothing Then
Return _BaseXNumber
Else
Return ToBaseString()
End If
End Function
Public Function GetBase10Number() As Double
If _Base10Number IsNot Nothing Then
Return _Base10Number
Else
Return ToBase10()
End If
End Function
Private Sub TrySetBaseSet(Values As List(Of Char))
For Each value As Char In _BaseXNumber
If Not Values.Contains(value) Then
Throw New ArgumentOutOfRangeException("The string has a value, " & value & ", not contained in the selected 'base' set.")
_CharacterArray.Clear()
DetermineNumberBase()
End If
Next
_CharacterArray = Values
End Sub
Private Sub TrySetBaseSet(LowValue As Integer, HighValue As Integer)
Dim HighLow As KeyValuePair(Of Integer, Integer) = GetHighLow()
If HighLow.Key < LowValue OrElse HighLow.Value > HighValue Then
Throw New ArgumentOutOfRangeException("The string has a value not contained in the selected 'base' set.")
_CharacterArray.Clear()
DetermineNumberBase()
End If
NumberBaseLow = LowValue
NumberBaseHigh = HighValue
End Sub
Private Function GetHighLow(Optional Values As List(Of Char) = Nothing) As KeyValuePair(Of Integer, Integer)
If Values Is Nothing Then
Values = _BaseXNumber.ToList
End If
Dim lowestValue As Integer = Convert.ToInt32(Values(0))
Dim highestValue As Integer = Convert.ToInt32(Values(0))
Dim currentValue As Integer
For Each value As Char In Values
If value <> DecimalSeparator AndAlso value <> GroupSeparator Then
currentValue = Convert.ToInt32(value)
If currentValue > highestValue Then
highestValue = currentValue
End If
If currentValue < lowestValue Then
currentValue = lowestValue
End If
End If
Next
Return New KeyValuePair(Of Integer, Integer)(lowestValue, highestValue)
End Function
Public Sub New(BaseXNumber As String)
_BaseXNumber = BaseXNumber
DetermineNumberBase()
End Sub
Public Sub New(BaseXNumber As String, NumberBase As Integer)
Me.New(BaseXNumber, Convert.ToInt32("0"c), NumberBase)
End Sub
Public Sub New(BaseXNumber As String, NumberBaseLow As Integer, NumberBaseHigh As Integer)
_BaseXNumber = BaseXNumber
Me.NumberBaseLow = NumberBaseLow
Me.NumberBaseHigh = NumberBaseHigh
End Sub
Public Sub New(Base10Number As Double)
_Base10Number = Base10Number
End Sub
Private Sub DetermineNumberBase()
Dim highestValue As Integer
Dim currentValue As Integer
For Each value As Char In _BaseXNumber
currentValue = Convert.ToInt32(value)
If currentValue > highestValue Then
highestValue = currentValue
End If
Next
NumberBaseHigh = highestValue
NumberBaseLow = Convert.ToInt32("0"c) 'assume 0 is the lowest
End Sub
Private Function ToBaseString() As String
Dim Base10Number As Double = _Base10Number
Dim intPart As Long = Math.Truncate(Base10Number)
Dim fracPart As Long = (Base10Number - intPart).ToString.Replace(DecimalSeparator, "")
Dim intPartString As String = ConvertIntToString(intPart)
Dim fracPartString As String = If(fracPart <> 0, DecimalSeparator & ConvertIntToString(fracPart), "")
Return intPartString & fracPartString
End Function
Private Function ToBase10() As Double
Dim intPartString As String = _BaseXNumber.Split(DecimalSeparator)(0).Replace(GroupSeparator, "")
Dim fracPartString As String = If(_BaseXNumber.Contains(DecimalSeparator), _BaseXNumber.Split(DecimalSeparator)(1), "")
Dim intPart As Long = ConvertStringToInt(intPartString)
Dim fracPartNumerator As Long = ConvertStringToInt(fracPartString)
Dim fracPartDenominator As Long = ConvertStringToInt(GetEncodedChar(1) & String.Join("", Enumerable.Repeat(GetEncodedChar(0), fracPartString.ToString.Length)))
Return Convert.ToDouble(intPart + fracPartNumerator / fracPartDenominator)
End Function
Private Function ConvertIntToString(ValueToConvert As Long) As String
Dim result As String = String.Empty
Dim targetBase As Long = GetEncodingCharsLength()
Do
result = GetEncodedChar(ValueToConvert Mod targetBase) & result
ValueToConvert = ValueToConvert \ targetBase
Loop While ValueToConvert > 0
Return result
End Function
Private Function ConvertStringToInt(ValueToConvert As String) As Long
Dim result As Long
Dim targetBase As Integer = GetEncodingCharsLength()
Dim startBase As Integer = GetEncodingCharsStartBase()
Dim value As Char
For x As Integer = 0 To ValueToConvert.Length - 1
value = ValueToConvert(x)
result += GetDecodedChar(value) * Convert.ToInt32(Math.Pow(GetEncodingCharsLength, ValueToConvert.Length - (x + 1)))
Next
Return result
End Function
Private Function GetEncodedChar(index As Integer) As Char
If _CharacterArray IsNot Nothing AndAlso _CharacterArray.Count > 0 Then
Return _CharacterArray(index)
Else
Return Convert.ToChar(index + NumberBaseLow)
End If
End Function
Private Function GetDecodedChar(character As Char) As Integer
If _CharacterArray IsNot Nothing AndAlso _CharacterArray.Count > 0 Then
Return _CharacterArray.IndexOf(character)
Else
Return Convert.ToInt32(character) - NumberBaseLow
End If
End Function
Private Function GetEncodingCharsLength() As Integer
If _CharacterArray IsNot Nothing AndAlso _CharacterArray.Count > 0 Then
Return _CharacterArray.Count
Else
Return NumberBaseHigh - NumberBaseLow + 1
End If
End Function
Private Function GetEncodingCharsStartBase() As Integer
If _CharacterArray IsNot Nothing AndAlso _CharacterArray.Count > 0 Then
Return GetHighLow.Key
Else
Return NumberBaseLow
End If
End Function
End Class
现在,要使代码通过Excel列循环:
Public Function GetColumnList(DataSheetID As String) As List(Of String)
Dim workingColumn As New BaseNumber("A")
workingColumn.SetCharacterArray("@ABCDEFGHIJKLMNOPQRSTUVWXYZ")
Dim listOfPopulatedColumns As New List(Of String)
Dim countOfEmptyColumns As Integer
Dim colHasData As Boolean
Dim cellHasData As Boolean
Do
colHasData = True
cellHasData = False
For r As Integer = 1 To GetMaxRow(DataSheetID)
cellHasData = cellHasData Or XLGetCellValue(DataSheetID, workingColumn.GetBaseXNumber & r) <> ""
Next
colHasData = colHasData And cellHasData
'keep trying until we get 4 empty columns in a row
If colHasData Then
listOfPopulatedColumns.Add(workingColumn.GetBaseXNumber)
countOfEmptyColumns = 0
Else
countOfEmptyColumns += 1
End If
'we are already starting with column A, so increment after we check column A
Do
workingColumn.SetNumber(workingColumn.GetBase10Number + 1)
Loop Until Not workingColumn.GetBaseXNumber.Contains("@")
Loop Until countOfEmptyColumns > 3
Return listOfPopulatedColumns
End Function
您会注意到Excel部分的重要部分是0在基于RE的数字中由 @识别。因此,我只是过滤 @它们中有一个 @的所有数字,然后得到正确的序列(a,b,c,...,z,aa,ab,ac,ac,...)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConvertToAnyBase
{
class Program
{
static void Main(string[] args)
{
var baseNumber = int.Parse(Console.ReadLine());
var number = int.Parse(Console.ReadLine());
string conversion = "";
while(number!=0)
{
conversion += Convert.ToString(number % baseNumber);
number = number / baseNumber;
}
var conversion2 = conversion.ToArray().Reverse();
Console.WriteLine(string.Join("", conversion2));
}
}
}