我不知道如何使用5列和n行创建一个二维数组,其中n =字符串/5中的字符,此值使用Math.Ceiling进行四舍五入。字符串中的字符在二维数组中从左到右、从上到下水平排列。
例如,如果输入的字符串是"DELICIOUS FOOD "2D数组应该是:
D E L I C
I O U S
F O O D X
在这种情况下,空格也算作一个字符。数组中剩余的空格应该用字符'X'标记。
我一直在使用数学天花板四舍五入字符串/5遇到语法问题,也对如何创建一个2D数组以及用原始字符串中的字符填充它感到困惑。
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Enter Customer name: ");
string customer = Console.ReadLine();
double customerLength = customer.Length;
double nRows = Math.Ceiling(customer.Length / 5);
char[,] table = new char[Convert.ToInt32(nRows)][5];
}
}
在找到解决方案之前,有几件事你需要研究一下。
- 如何在c#中声明2D数组
- c#中的整数除法和浮点除法
如果你理解了这些概念,你可以想出一个没有错误的解决方案。
// Displays the prompt "Enter Customer name:" in the console window
Console.WriteLine("Enter Customer name: ");
// Reads a string input from the user through the console and assigns it to the variable "customer"
var customer = Console.ReadLine();
// Starts an "if" statement to check if the "customer" variable is not null.
if (customer != null)
{
// Calculates the number of rows needed to display the customer name
var n = (customer.Length / 5.0);
// Rounds up the number of rows to the nearest integer value
var nRows = Math.Ceiling(n);
// Creates a 2D char array with the calculated number of rows and 5 columns
var table = new char[Convert.ToInt32(nRows), 5];
// Initializes the index variable to 0
var index = 0;
// Iterates through each row of the "table" array
for (var row = 0; row < table.GetLength(0); row++)
{
// Iterates through each column of the "table" array
for (var column = 0; column < table.GetLength(1); column++)
{
// Assigns the character value of "customer[index]" to the "table" array if "index" is within the range of the "customer" string, otherwise assigns 'X'
table[row, column] = customer.Length <= index ? 'X' : customer[index];
// Writes the character value to the console followed by a space
Console.Write($"{table[row, column]} ");
// Increments the index variable
index++;
}
// Writes a newline character to the console to start a new row
Console.WriteLine();
}
}
让我们为您的任务提取方法。我们已知value
和colCount
,我们想要得到char[,]
。
- 首先,我们应该分配
char[,]
数组:我们希望value.Length / colCount
行加上额外的行,如果value.Length
不均匀划分。 - 我们应该把一个字符一个字符地放入数组中:当列是
index % colCount
时,row
是index / colCount
。 代码:
private static char[,] ToTable(string value, int colCount) {
if (value is null)
throw new ArgumentNullException(nameof(value));
if (colCount <= 0)
throw new ArgumentOutOfRangeException(nameof(colCount));
char[,] result = new char[
value.Length / colCount + (value.Length % colCount == 0 ? 0 : 1),
colCount];
// Fill the array with `X`:
for (int r = 0; r < result.GetLength(0); ++r)
for (int c = 0; c < result.GetLength(1); ++c)
result[r, c] = 'X';
for (int i = 0; i < value.Length; ++i)
result[i / result.GetLength(1), i % result.GetLength(1)] = value[i];
return result;
}
小提琴
首先,如何使用cols
列计算长度为n
的字符串所需的行数:
rows = (n + cols - 1) / cols
使用整数除法进行计算,以避免使用浮点数。
为了填充数组,最好将其视为1D数组,这样我们就可以将文本复制到其中。因为2D数组是按行为主的顺序存储的,所以这可以正常工作。
我们可以通过使用辅助方法为2D数组创建Span<char>
来实现这一点,例如:
public static Span<T> AsSpan<T>(Array array)
{
return MemoryMarshal.CreateSpan(
ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array)),
array.Length);
}
把这些放在一起,我们得到以下内容:
string text = "DELICIOUS FOOD";
int cols = 5;
int rows = (text.Length + cols - 1) / cols;
var array = new char[rows, cols];
var span = AsSpan<char>(array); // Create a span that encompasses all the elements of 'array' as a single span.
text.CopyTo(span); // Copy the text to the span; this will wrap at the correct places.
span.Slice(text.Length).Fill('X'); // Fill the remainder of the span with 'X'.
请注意,span.Slice(text.Length)
返回一个新的span,从text.Length
元素的偏移量开始-这是我们需要开始用'X'字符填充最后一行的剩余部分的地方。
还需要注意的是,Span<T>.Fill(item)
只是用指定的项目填充该span。
把这些放到一个测试控制台应用程序中(在线尝试):
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Console1;
public static class Program
{
public static void Main()
{
string text = "DELICIOUS FOOD";
int cols = 5;
int rows = (text.Length + cols - 1) / cols;
var array = new char[rows, cols];
var span = AsSpan<char>(array); // Create a span that encompasses all the elements of 'array' as a single span.
text.CopyTo(span); // Copy the text to the span; this will wrap at the correct places.
span.Slice(text.Length).Fill('X'); // Fill the remainder of the span with 'X'.
// Print the result.
for (int r = 0; r < rows; ++r)
{
for (int c = 0; c < cols; ++c)
{
Console.Write(array[r, c]);
}
Console.WriteLine();
}
}
public static Span<T> AsSpan<T>(Array array)
{
return MemoryMarshal.CreateSpan(
ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array)),
array.Length);
}
}
这个输出:
DELIC
IOUS
FOODX
如果你使用的是。net 6(或更高版本),你可以使用新的LINQChunk
方法:
string s = "DELICIOUS FOOD";
int batchSize = 5;
int len = s.Length;
int nBatches = (int)Math.Ceiling((double)len / batchSize);
var parts = s.PadRight(batchSize * nBatches, 'X').Chunk(batchSize).ToArray();
foreach(var part in parts)
{
Console.WriteLine(string.Join(" ", part));
}
输出:
D E L I C
I O U S
F O O D X