C#-计算字符串列表中的周围字符之和

时间:2018-10-20 10:19:11

标签: c# arrays string char

假设我在List<string>中有4个字符串。我在这里以x y和z为例,但可以是任何字符。

"xyyy",
"yyyz",
"yyxz",
"yyyy"

在该字符串列表中,如何根据x计算环绕Y的位置?因此,以X为目标并计算所有接触Y点,请注意,在这种情况下,我希望忽略z而仅以y为目标。如果x在左上角,那将是3个感人的y点

我开始使用ToCharArray()遍历字符串,并跟踪列表中我所在位置的上下限,但是它很快就变成了递归地狱。我正在寻找更好的解决方案,以遍历每个列表并检查其是否具有上下边界,然后遍历所有字符。

为澄清起见:

让我们放大列表中的前两个字符串

"xyyy",
"yyyz"

我们可以清楚地看到x触碰到y的右侧(对角线),y触及其下方的y,这意味着总共有3个y触及ys。

然后我必须输出x触摸y列表中PER字符串的次数来控制台-换句话说:每行

2 个答案:

答案 0 :(得分:1)

如果您知道行长,并且知道目标的索引(通过扫描整个数组以查找x,那么计算相邻平方的索引就很简单了

int i= //some index;
int l= //row length;
int y = i/l;//the floored quotient is the y offset
int x = i % l;//the remainder is the x offset

//Note that a negative result or a number greater than the whole array length is illegal so you have to catch that in your logic
int n= i-w;// skip a row back
int s = i+w;// skip a row forward
//if we hit the end then illegal else adjacent
int e= x+1 ==l? -1 : i+1;  
int w= x-1 <0? -1: i-1;

///如果不想将字符串列表转换为2D数组,则按上述方式逐行进行,但是y现在只是成为Lst的索引,而x是对字符串的扫描。当您找到目标字符时,其相邻值将为:

char n = list[y-1][x];
char s = list[y+1][x];
char e = list[y][x+1];
char w = list[y][x-1];
char sw= list[y+1][x-1];
char se= list[y+1][x+1];
//etc.

只需记住仅检查catch IndexOutOfRange的边界,然后继续循环,即可避免大量繁琐的专门检查逻辑。

这些是我对餐巾纸的估算,您可能需要查看图片。另外,如果您想要对角线,我将其保留为练习。提示:对新产生的索引使用相同的逻辑。

如果您具有字符值,则有很多求和它们的示例,我认为困难的部分是找到邻接。

答案 1 :(得分:0)

这是您想要的描述的粗略实现。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Touching {

    class CharFinder {

        public static List<Tuple<int, int>> counted = new List<Tuple<int, int>>();

        public static void Main(string[] args) {
            getInputs(out char target, out char indexed, out List<string> lines);
            List<Tuple<int, int>> indexes = new List<Tuple<int, int>>();
            for (int i = 0; i != lines.Count; i++) {
                for (int j = 0; j != lines[i].Length; j++) {
                    if (lines[i][j] == indexed) {
                        indexes.Add(new Tuple<int, int>(i, j));
                    }
                }
            } int tCount = countNeighbor(lines, indexes[0], target);
            for (int i = 0; i != indexes.Count; i++) {
                tCount += countNeighbor(lines, indexes[i], target);
            } Console.WriteLine(tCount.ToString()); 
            Console.ReadLine();
        }

        public static int countNeighbor(List<string> grid, Tuple<int, int> ind, char target) {
            int count = 0;
            for (int i = ind.Item1 - 1; i < ind.Item1 + 2; i++) {
                if (i == -1 || i >= grid.Count) { continue; } 
                for (int j = ind.Item2 - 1; j < ind.Item2 + 2; j++) {
                    if (j == -1 || j >= grid[i].Length) { continue; }
                    if (grid[i][j] == target && !counted.Contains(new Tuple<int, int>(i, j))) { 
                        counted.Add(new Tuple<int, int>(i, j));
                        count++; 
                    }
                }
            } return count;
        }

        public static void getInputs(out char target, out char indexed, out List<string> strs) {
            int lines = 0;
            strs = new List<string>();
            while (true) {
                Console.Clear();
                Console.Write("Number of lines?: ");
                try { lines = Convert.ToInt32(Console.ReadLine()); if (lines < 1) { throw new Exception(); } break; }
                catch { Console.WriteLine("ERROR: Must be a positive integer."); Console.ReadLine(); }
            } Console.Clear();
            Console.Write("Target?: ");
            target = Console.ReadLine()[0];
            Console.Clear();
            Console.Write("Indexed?: ");
            indexed = Console.ReadLine()[0];
            for (int i = 0; i < lines; i++) {
                strs.Add(Console.ReadLine());
            }
        }
    }
}