Transposicion de Columnas en una Matriz en c++

Hola tengo una matriz char inicializada de la siguiente manera:

#include <iostream>  

using namespace std;  

main(){

char matriz[6][5]={
{'F','H','V','D','U'},
{'E','L','Q','U','E'},
{'P','E','R','S','E'},
{'V','E','R','A','A'},
{'L','C','A','N','Z'},
{'A','Z','Z','Z','Z'}};

}

Y necesito transponer las columnas, ordenando alfabéticamente la primera fila, es decir, la fila que contiene {'F','H','V','D','U'}.

La matriz que necesito obtener es la siguiente:

char matriz[6][5]={
{'D','F','H','U','V'},
{'U','E','L','E','Q'},
{'S','P','E','E','R'},
{'A','V','E','A','R'},
{'N','L','C','Z','A'},
{'Z','A','Z','Z','Z'}};

He logrado ordenar alfabéticamente la primera fila únicamente, pero no logro como poder mover el resto de la columna para efectuar el ordenamiento como un solo bloque.

Actualizacion:

Ok finalmente logre poder trasponerla pero ahora por lo menos si la primera fila de la matriz tiene letras iguales, se ordenan alfabeticamente pero se transponen los valores de solamente una de las dos columnas. He aqui el codigo que tengo para trasponerlas.

    for(int j=0;j<largo;j++){
        for(int i=0;i<largo;i++){
            if(textoB[0][j]==texto[0][i]&&textoB[0][j+1]==texto[0][i]){
                texto[0][i]='*';
                for(int k=1;k<fila;k++){
                    textoB[k][j]=texto[k][i];
                }
            }


            else if(textoB[0][j]==texto[0][i])
                for(int k=1;k<fila;k++){
                    textoB[k][j]=texto[k][i];
                }
        }
    }

Siendo texto la matriz original desordenada y textoB la matriz original con primera fila ordenada alfabéticamente (desordenada en las demás espacios).

1
задан 31.03.2016, 03:10
2 ответа

Ты не напечатал твой код так что мы не можем знать, в чем ты ошибся, мог бы быть включенным случай: Что ты попробовал?.

я не добиваюсь, как мочь двигать оставшуюся часть колонны, чтобы осуществлять распоряжение как единственный блок

Проблема состоит в том, что ты работаешь с массивом двух размеров, который делает немного более некомфортабельным обмениваться информацией о колоннах, ты не можешь относиться к ним как к "единственному блоку", так как они принадлежат различным блокам. В памяти будь должен иметь похожий аспект в...

fila       |    0    |    1    |    2    |    3    |    4    |    5    |
columna    |0|1|2|3|4|0|1|2|3|4|0|1|2|3|4|0|1|2|3|4|0|1|2|3|4|0|1|2|3|4|
memoria    |F|H|V|D|U|E|L|Q|U|E|P|E|R|S|E|V|E|R|A|A|L|C|A|N|Z|A|Z|Z|Z|Z|

Так что ты должен пробегать линии одни из-за одной и обмениваться стоимостью columas, которая он интересует тебя. Приближение, которое я советую тебе, - следующее:

for (std::size_t fila = 0u; fila != FILAS; ++fila)
{
    // 'izquierda' y 'derecha' son las columnas que se quieren intercambiar
    std::swap(matriz[fila][izquierda], matriz[fila][derecha]);
}

Я использовал решение, основанное на шаблонах, которая позволяет массивы двух размеров типов и произвольных размеров (всякий раз когда облегченный тип располагал оператором <):

template <typename TIPO, std::size_t FILAS, std::size_t COLUMNAS>
void intercambia_columnas(TIPO (&matriz)[FILAS][COLUMNAS], std::size_t izquierda, std::size_t derecha)
{
    for (std::size_t fila = 0u; fila != FILAS; ++fila)
    {
        std::swap(matriz[fila][izquierda], matriz[fila][derecha]);
    }
}
template <typename TIPO, std::size_t FILAS, std::size_t COLUMNAS>
int compara_columnas(const TIPO (&matriz)[FILAS][COLUMNAS], std::size_t izquierda, std::size_t derecha)
{
    for (std::size_t fila = 0u; fila != FILAS; ++fila)
    {
        const auto i = matriz[fila][izquierda], d = matriz[fila][derecha];

        if (i != d)
        {
            return i < d ? -1 : 1;
        }
    }

    return 0;
}

template <typename TIPO, std::size_t FILAS, std::size_t COLUMNAS>
void ordena_matriz(TIPO (&matriz)[FILAS][COLUMNAS])
{
    for (std::size_t a = 0u; a != COLUMNAS - 1u; ++a)
    {
        for (std::size_t b = a + 1u; b != COLUMNAS; ++b)
        {
            if (compara_columnas(matriz, a, b) > 0)
            {
                intercambia_columnas(matriz, a, b);
            }
        }
    }
}

Ты можешь видеть код функционируя в Wandbox.

Изданный

Ты остаешься, не печатая твоего полного кода; в твой код перемещения ему не хватает контекст следовательно трудный знать в каком недостатке.

Код, который ты используешь для trasponer, только сравнивает первую линию (texto[0]) но если ты хочешь упорядочить отношение колонны, ты должен иметь в виду все линии, которые составляют колонну, не только первая.

С другой стороны, завись от стоимости largo, ты можешь читать вне массива в операции textoB[0][j+1] (так как предел j он largo); кроме того это сравнение неправильное, так как ты не всегда будешь нуждаться в том, чтобы сравнить колонну, следующую за колонной j.

1
ответ дан 24.11.2019, 14:41

Я помещаю здесь внизу решение, которое я объясняю в том же коде. И я не могу прекращать комментировать тебе, что в C ++ arrays и указатели - последний ресурс, никогда первый. Ну, равный, здесь пойди...

#include <iostream>  
#include <map>

const int f = 6;
const int c = 5;

void obtener_orden(const char* m, int* n)
{
    // en los c caracteres de m está la primera fila
    // F, H, V, D, U
    // la idea es que si su orden actual es
    // 0, 1, 2, 3, 4
    // pase a ser 
    // 3, 0, 1, 4, 2 
    // o sea: 
    // D, F, H, U, V
    // y guardarse ese nuevo orden en n:

    // como soy muy vago, me voy a ayudar con un std::multimap 
    // http://es.cppreference.com/w/cpp/container/multimap
    std::multimap<char, int> posiciones;
    for (int i = 0; i < c; ++i) {
        posiciones.insert(std::make_pair(m[i], i));
    }

    // lleno el array n con el nuevo orden:
    int i = 0;
    std::cout << "nuevo orden = ";
    for (std::multimap<char, int>::iterator it = posiciones.begin(); it != posiciones.end(); ++it) {
        std::cout << (*it).first << " => " << (*it).second << "; ";
        n[i++] = (*it).second;
    }
    std::cout << '\n';
}

void ordenar_matriz(char* m, int* orden)
{
    // acá la idea es aplicar el nuevo orden que figura en el array orden
    // a la matriz nueva, que también va a tener f filas de c columnas,

    char nueva[f][c];

    for (int i = 0; i < f; ++i) {      
        for (int j = 0; j < c; ++j) {  
            nueva[i][j] = m[i*c + orden[j]];
        }
    }

    // y mostramos la nueva matriz con el nuevo orden:
    for (int i = 0; i < f; ++i) {      // recorre cada fila
        for (int j = 0; j < c; ++j) {  // y recorre cada columna
            std::cout << nueva[i][j] << ' ';
        }
        std::cout << '\n';
    }
    std::cout << '\n';
}

int main() {  // main() devuelve int

    char matriz[f][c] = {
        { 'F','H','V','D','U' },
        { 'E','L','Q','U','E' },
        { 'P','E','R','S','E' },
        { 'V','E','R','A','A' },
        { 'L','C','A','N','Z' },
        { 'A','Z','Z','Z','Z' } };

    int orden[c] = {0};

    obtener_orden(&matriz[0][0], orden);

    ordenar_matriz(&matriz[0][0], orden);

}
0
ответ дан 24.11.2019, 14:41