查找并列出字符串C ++中的所有char簇

时间:2018-01-09 10:02:46

标签: c++ string algorithm

我正在寻找帮助在C ++中找到字符串中所有字符簇的帮助。确切的任务是:

  

给出以下“2D字符串”(在C ++表达式中):

string text =
  "#################aa##a###c######\n" +
  "####bbbbaaaabbbbbaaaaa###ccc##cc\n" +
  "#o##bbbbaaaabbbbbaaaaa###c#c##cc\n" +
  "#oo#bbbbaeeabbbbbbbbaa##cc#ccccc\n" +
  "#o##bbbbaeeabbbbbaaaaaa#cc#####c\n" +
  "#o##bbbbaaaabbbbbaaaaaa#cc#####c\n";
  

编写一个程序,计算相同>符号的每个连续区域的区域。如果两个相等的符号在一行或一列中是邻居,则它们属于同一区域。不计算换行符(\ n),它们只是>形成2D字符串。

     

主要功能应该是递归的。

     

提示:使用额外的2D数组标记2D字符串中的每个符号(如果>已经计数或未计数)。逐行扫描阵列,直到找到未计数的符号>。然后,从此>符号开始运行递归区域计算功能。继续,直到所有符号都标记为计数。

     

程序输出应该(或多或少)看起来像:

Region of symbols #, area …
Region of symbols a, area …
Region of symbols #, area …
Region of symbols c, area …

我目前的代码如下:

#include <iostream>
#include <string>
using namespace std;

int cords (string str, int x, int y) {
    int length, i, position, lines = 0, x_max, y_max;
    char symbol;
    length = str.length();
    for (i = 0; i < length; i++) {
        symbol = str[i];
        if (symbol == '\n')
            lines++;
    }
    length -= lines;
    x_max = length / lines;
    y_max = length / x_max;
    position = x - 1 + (y - 1) * x_max + y - 1;

    if (x <= x_max && y <= y_max)
        return position;
}

int clusterMiner (char symbol, string str, int x, int y, int counter, int last) {
    if (x > 32 || y > 6) {
        return counter;
    } else {
        if (str[cords(str, x++, y)] == symbol) {
            counter++;
            return clusterMiner(symbol, str, x++, y, counter, x);
        } else if (str[cords(str, 1, y++)] == symbol) {
            return clusterMiner(symbol, str, 1, y++, counter, x);
        }
    }
}

int main () {
    int length, lines, i, j, k, l, counter;
    string text = // 32 elements per line
    "#################aa##a###c######\n" // 32
    "####bbbbaaaabbbbbaaaaa###ccc##cc\n" // 64
    "#o##bbbbaaaabbbbbaaaaa###c#c##cc\n" // 96
    "#oo#bbbbaeeabbbbbbbbaa##cc#ccccc\n" // 128
    "#o##bbbbaeeabbbbbaaaaaa#cc#####c\n" // 160 
    "#o##bbbbaaaabbbbbaaaaaa#cc#####c\n"; // 192

    counter = clusterMiner('#', text, 1, 1, 0, 0);
    cout << counter;

    return 0;
}

Cords函数只是为了更容易与字符串的两个维度进行交互。

我不知道接下来该做什么。现在,程序只计算一些符号,因为它停在第一个不同的符号,忽略了连接到其他节点的符号。

谢谢!

1 个答案:

答案 0 :(得分:0)

首先,不要一直计算x_max和y_max,只需执行一次并将其存储在变量中。然后,您将不得不遍历整个字段:

char get(int x, int y)
{
    // + 1: the newline!!!
    return field[x + y * (x_max + 1)];
}

void countAll()
{
    calculateMaxima();
    // created your visited array now
    for(unsigned int y = 0; y <= y_max; ++y)
    {
        for(int x = 0; x <= x_max; ++x)
        {
            if(!visited[x, y])
            {
                count = 0;
                search(get(x, y), x, y);
                // output count here...
            }
        }
    }
}

每当我们遇到一个尚未访问的角色时,我即一个新的,我们开始一个新的搜索。对于每次搜索,我们必须考虑每个当前位置{x, y}的四个邻居:
{x +/- 1, y}{x, y +/- (x_max + 1}(除了边缘处的位置,它们更少)。所以你的搜索可能如下所示:

void visit(char symbol, int x, int y)
{
    if(!visited[x][y] && get(x, y) == symbol)
    {
        ++count;
        ++visited[x][y] = true;
    }
    search(symbol, x, y);
}

void search(char symbol, int x, int y)
{
    if(x > 0)
        visit(x - 1, y);
    if(x < max_x)
        visit(x + 1, y);
    if(y > 0)
        visit(x, y - 1);
    if(y < max_y)
        visit(x, y + 1);
}

现在,我假设计数,访问并且x / y_max是一些全局变量。 Cleaner,因为我们是C ++,将为此目的编写一个单独的类:

class ClusterMiner
{
    unsigned int count;
    std::string field;
    // ...

    void visit(char symbol, int x, int y);
    void search(char symbol, int x, int y);
    // ...
public:
    void countAll();
};

代码未经测试且不完整,只能为您提供必要的提示以找到您的方式......

旁注:如果您有相同字符的未连接区域,则会检测到这些区域。如果不需要,您可以总结结果e。 G。在std::map<char, unsigned int>中,在完成计数后迭代这个...