Jump to content

Recommended Posts

Posted (edited)

Boa noite pessoal,

Estou com uma dificuldade tremenda em ler um .txt com o seguinte conteúdo:

0 0 0 0 0 0 0 0 0 0

0 1 1 1 0 0 1 1 1 0

0 1 1 1 0 0 1 1 1 0

0 0 0 0 0 0 0 0 0 0

0 1 1 1 0 0 1 1 1 0

0 1 1 1 0 0 1 1 1 0

0 0 0 0 0 0 0 0 0 0

0 1 1 1 0 0 1 1 1 0

0 1 1 1 0 0 1 1 1 0

0 0 0 0 0 0 0 0 0 0

E depois precisava de guardar esse conteúdo numa matriz para que puder substituir os valores de outra matriz já criada.

main() {

// criar mapa vazio
for(int y=0;y<m;y++) {

	for(int x=0;x<n;x++){

	 map[x][y]=0;


*****Trocar valores da matriz criada*******

	  }
 }
}

Alguém me pode ajudar pf?

Este código deveria fazer o que quero, mas guarda num vector e eu precisava que fosse numa matriz 10x10 e para alem disso os valores que apresenta não tem nada a ver com o que tenho no ficheiro.

#include <stdio.h> //para FILE, NULL, EOF, fopen(), fclose() e getw().
#include <stdlib.h> //para exit().
#include <conio.h> //para getch().
main()
{
FILE *fp; //ponteiro para um arquivo.
int numeros[10]; //para armazenar os números lidos do arquivo.
int cont=0; //para indexar a matriz,
fp = fopen("dados.txt", "rb"); //abre arquivo p/ leitura.
if(fp == NULL) //se houve um erro ao tentar abrir o arquivo.
{
 printf("Erro ao abrir o arquivo!");
 exit(1); //finaliza programa.
}
while( cont < 10 ) //loop para ler os int do arquivo.
{
 numeros[cont] = getw(fp); //lê números inteiros no arquivo apontado por fp.
 printf("%d ", numeros[cont]); //mostra os números na tela.
 cont++;
}
printf("\n\nDados lidos com sucesso!");
printf("\nPressione uma tecla para finalizar...");
getch();
fclose(fp); //fecha o arquivo.
}
Edited by maxfyre
geshi
Posted

Boa noite,

na minha opiniao acho que podes fazer um ciclo while com condicao fgets(...) != NULL

e dentro do ciclo while usar strtok e outro ciclo while para "partir" a linha por espaço!

assim sendo, o programa pegava na primeira linha, dividia por espaços, e á medida que vai dividindo vai colocando na matriz. Tipo "matriz[linhas][coluna]"

Dentro do segundo ciclo (strtok) incrementa a coluna, e fora do segundo while, no fim do primeiro incrementa a linha.

Nao esquecer de usar qualquer coisa como "matriz[linha][coluna] = atoi(tokenVariavel)"

Posted

Boa noite,

na minha opiniao acho que podes fazer um ciclo while com condicao fgets(...) != NULL

e dentro do ciclo while usar strtok e outro ciclo while para "partir" a linha por espaço!

assim sendo, o programa pegava na primeira linha, dividia por espaços, e á medida que vai dividindo vai colocando na matriz. Tipo "matriz[linhas][coluna]"

Dentro do segundo ciclo (strtok) incrementa a coluna, e fora do segundo while, no fim do primeiro incrementa a linha.

Nao esquecer de usar qualquer coisa como "matriz[linha][coluna] = atoi(tokenVariavel)"

não consegues complicar ainda mais isso ?

olha bem para o problema : sabes quantas linhas tens, sabes quantas colunas tens. o ficheiro é lido em três linhas de código

IRC : sim, é algo que ainda existe >> #p@p
Posted (edited)
// le ficheiro txt e
vector<vector<int> > temp;
ifstream file("estantes.txt");// documento com as estantes
string line;
while (getline(file, line))
{
	temp.push_back(vector<int>());
	istringstream ss(line);
	int value;
	while (ss >> value)
	{
		temp.back().push_back(value);
	}
}
for (int x = 0; x < temp.size(); x++)
{
	for (int y = 0; y < temp[y].size(); y++)
	{

			if(temp[x][y]==0)
				map[x][y]=0;//caminho livre
			else if(temp[x][y]==1)
				map[x][y]=1; //obstaculo

	}
	cout << endl;
}

Consegui resolver o problema desta forma.

Pode não ser a melhor mas para já funciona 😉 .

Mas agora surge outro problema que ainda estou a ver como resolver.

Por exemplo importando uma matriz como esta:

0 0 0 0 0 0 0 0 0 0

0 1 1 1 0 0 1 1 0 0

0 1 1 1 0 0 1 1 0 0

0 0 0 0 0 0 1 1 0 0

0 0 0 0 0 0 0 0 0 0

Queria transforma-la numa assim:

0 3 3 3 0 0 0 0 0 0

0 1 1 1 0 3 1 1 3 0

0 1 1 1 0 3 1 1 3 0

0 3 3 3 0 3 1 1 3 0

0 0 0 0 0 0 0 0 0 0

Em que:

  • "0" corresponde ao caminho livre
  • "1" corresponde aos obstáculos
  • "3" corresponde aos pontos de picking

Alguém tem uma ideia como é que eu devo fazer para atribui os pontos de picking automaticamente?

Obrigado.

Edited by maxfyre
Posted

código flexivel para leitura de um ficheiro com essa estrutura (não saber o tamanho do mapa existente no ficheiro)

#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

#define FILE "input.txt"

int main(int argc, char** argv) {
   vector<vector<int>> map;

   {   // for auto destruction of file stream object
       ifstream file(FILE);
       vector<int> buffer;

       // file reading cycle
       while (file.good()) {
           // check for end of line
           if (file.peek() == '\n') {
               // store the buffered/readed line
               if (buffer.size() > 0)
                   map.push_back(buffer);
               buffer.clear();
           }

           // read the next number
           int n;
           file >> n;

           // check if the number was read and store it in the buffer vector
           if (file.good())
               buffer.push_back(n);
       }

       // check if there still a line to be stored in the map
       if (buffer.size() > 0)
           map.push_back(buffer);
   }

   // map presentation cycle
   for (size_t row = 0; row < map.size(); ++row) {
       for (size_t column = 0; column < map[row].size(); ++column)
           cout << ' ' << map[row][column];
       cout << endl;
   }

   return 0;
}

Alguém tem uma ideia como é que eu devo fazer para atribui os pontos de picking automaticamente?

não porque não dás qualquer regra sobre como esses 3's deverão ser colocados

IRC : sim, é algo que ainda existe >> #p@p
Posted (edited)

Não dei regra porque os meu problema está mesmo ai.

Eu queria que o programa identifica-se se o obstáculo esta na vertical ou na horizontal e atribui-se o valor 3 nos pontos de acesso que seriam como exemplifiquei em cima.

E não estou a ver como o posso fazer.

Edited by maxfyre
Posted

a questão aqui é que se não sabes o que queres fazer, mais ninguém irá saber, da mesma maneira que ninguém irá saber te dizer o que fazer.

dizer que queres colocar uns 3's quaisquer sem uma regra definida, só pode resultar em uma resposta como:

- cria dois número aleatório (x e y) e coloca um 3 nessa posição ...

estás a ver o problema ?

IRC : sim, é algo que ainda existe >> #p@p
Posted (edited)

Mas o que eu quero fazer já disse só não sei como fazer, posso é me ter explicado mal.

Eu quero importar um .txt para o programa com uma matriz deste género:

0 0 0 0 0 0 0 0 0 0

0 1 1 1 0 0 1 1 0 0

0 1 1 1 0 0 1 1 0 0

0 0 0 0 0 0 1 1 0 0

0 0 0 0 0 0 0 0 0 0

Quero que o programa encontre tudo que é valor "1" na matriz (estou a tentar com algo assim)

for(int x=0;x<m;x++)
   {
    for(int y=0;y<n;y++){	   
	 if (map[x][y]==1){
	  if(map[x-1][y]==0 && map[x][y-1]==0 && map[x+1][y]==1&& map[x][y+1]==1){//canto superior esquerdo
	   map[x][y-1]=3;		  
   }else if(map[x-1][y]==0 && map[x][y-1]==1 && map[x+1][y]==1&& map[x][y+1]==0){//canto inferior esquerdo
 map[x][y+1]=3;
   }else if(map[x-1][y]==1 && map[x][y-1]==0 && map[x+1][y]==1&& map[x][y+1]==1){// centro cima
 map[x][y-1]=3;
   }
   else if(map[x-1][y]==1 && map[x][y-1]==1 && map[x+1][y]==1&& map[x][y+1]==0){// centro baixo
 map[x][y+1]=3;
   }
   else if(map[x-1][y]==1 && map[x][y-1]==0 && map[x+1][y]==0&& map[x][y+1]==1){// canto superior direito
 map[x][y-1]=3;
   }
   else if(map[x-1][y]==1 && map[x][y-1]==1 && map[x+1][y]==0&& map[x][y+1]==0){// canto inferior direito
 map[x][y+1]=3;
   }


  }
 }
}

E após encontrar o valor "1" verificar onde estão os valores "0" e atribuir o valor 3 (tentei com o switch case mas não estou a conseguir)

  • caso 1 -> um á esquerda && um em baixo && um à direirta && zero em cima -> atribui o valor 3 no campo em cima
  • caso 2 -> um á esquerda && zero em baixo && um à direirta && um em cima -> atribui o valor 3 no campo em baixo
  • caso 3 -> zero á esquerda && um em baixo && um à direirta && zero em cima -> atribui o valor 3 no campo em cima
  • caso 4 -> zero á esquerda && zero em baixo && um à direirta && um em cima -> atribui o valor 3 no campo em baixo
  • caso 5 -> um á esquerda && um em baixo && zero à direirta && zero em cima -> atribui o valor 3 no campo em cima
  • caso 6 -> um á esquerda && zero em baixo && zero à direirta && um em cima -> atribui o valor 3 no campo em baixo

Estou a tentar aplicar estas regras, para ficar algo assim:

0 3 3 3 0 0 0 0 0 0

0 1 1 1 0 3 1 1 3 0

0 1 1 1 0 3 1 1 3 0

0 3 3 3 0 3 1 1 3 0

0 0 0 0 0 0 0 0 0 0

​mas essas regras são só para quando o obstáculo está da horizontal eu queria que o programa identifica-se se está na vertical ou na horizontal e preenche-se com o valor 3 como está na matriz em cima

Edited by maxfyre
Posted

vês como já consegues perceber que para resolver um problema necessitas de regras ?

programação não é mais do que escrever essas regras numa linguagem de programação qualquer de modo a que o computador as perceba e aplique.

(é por isso que IA é algo que muito pensam ser impossivel)

a tua solução é esta:

#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

#define FILE "input.txt"

class Map {
public:
   const int EMPTY_SPACE = 0;
   const int INTERACTION_SPACE = 3;

private:
   vector<vector<int>> map;

public:
   Map(const string filename) {
       ifstream file(filename);
       vector<int> buffer;

       // file reading cycle
       while (file.good()) {
           // check for end of line
           if (file.peek() == '\n') {
               // store the buffered/readed line
               if (buffer.size() > 0)
                   map.push_back(buffer);
               buffer.clear();
           }

           // read the next number
           int n;
           file >> n;

           // check if the number was read and store it in the buffer vector
           if (file.good())
               buffer.push_back(n);
       }

       // check if there still a line to be stored in the map
       if (buffer.size() > 0)
           map.push_back(buffer);
   }

   void outputToConsole(void) {
       print(map);
   }

   void markRectangularObjectInteractionPoints(int id) {
       // auxiliary map used to ignore already processed posisitons
       vector<vector<int>> aux = getAuxiliaryMap();

       // map search cycles
       for (size_t row = 0; row < map.size(); ++row) {
           for (size_t column = 0; column < map[row].size(); ++column) {
               // check if the current iterated position is of the searched object
               // and as not been processed already
               if (!aux[row][column] && map[row][column] == id) {
                   size_t width = 0;
                   size_t height = 0;

                   // object width determination
                   while (map[row][column + width] == id)
                       ++width;

                   // object height determination
                   while (map[row + height][column] == id)
                       ++height;

                   // marking the object (positions) as processed
                   for (size_t i = 0; i < height; ++i)
                       for (size_t j = 0; j < width; ++j)
                           aux[row + i][column + j] = id;

                   // check if the object is in the horizontal
                   if (width > height) {
                       // mark the above positions as interaction positions
                       if (row > 0)
                           for (size_t i = 0; i < width; ++i)
                               map[row - 1][column + i] = INTERACTION_SPACE;

                       // mark the below positions as interaction positions
                       if (row + height < map.size())
                           for (size_t i = 0; i < width; ++i)
                               map[row + height][column + i] = INTERACTION_SPACE;
                   // check if the object is in the vertical
                   } else if (width < height) {
                       // mark the left positions as interaction positions
                       if (column > 0)
                           for (size_t i = 0; i < height; ++i)
                               map[row + i][column - 1] = INTERACTION_SPACE;

                       // mark the right positions as interaction positions
                       if (column + width < map[row].size())
                           for (size_t i = 0; i < height; ++i)
                               map[row + i][column + width] = INTERACTION_SPACE;
                   } else {
                       // SQUARE ... WHAT DO DO ?
                   }
               }
           }
       }
   }

private:
   vector<vector<int>> getAuxiliaryMap(void) {
       vector<vector<int>> aux;

       // create an auxiliary map (same size) but marked all as empty
       for (size_t row = 0; row < map.size(); ++row) {
           vector<int> buffer;
           for (size_t column = 0; column < map[row].size(); ++column)
               buffer.push_back(EMPTY_SPACE);
           aux.push_back(buffer);
       }

       return aux;
   }

   void print(vector<vector<int>> map) {
       // print map into the console
       for (size_t row = 0; row < map.size(); ++row) {
           for (size_t column = 0; column < map[row].size(); ++column)
               cout << ' ' << map[row][column];
           cout << endl;
       }
   }
};

int main(int argc, char** argv) {
   Map map(FILE);

   map.markRectangularObjectInteractionPoints(1); // object id on map = 1
   map.outputToConsole();

   return 0;
}
IRC : sim, é algo que ainda existe >> #p@p
Posted (edited)

Obrigado pela ajuda já consigo atribuir o valor 3 no sitio correto para os obstáculos horizontais.(entretanto mudei o valor para 5).

A matriz está com este aspecto.

0 5 5 5 0

0 1 1 1 0

0 1 1 1 0

0 5 5 5 0

0 0 0 0 0

Agora eu queria pesquisar na matriz o primeiro valor 5 e mudar para 2

0 2 5 5 0

0 1 1 1 0

0 1 1 1 0

0 5 5 5 0

0 0 0 0 0

Depois queria voltar a pesquisar o próximo valor 5 e mudar para 4

0 2 4 5 0

0 1 1 1 0

0 1 1 1 0

0 5 5 5 0

0 0 0 0 0

Então de seguida quero preencher uma nova matriz com a distancia correspondente entre o valor 2 e o valor 4.

Depois quero passar o valor 4 a 6 e pesquisar o próximo valor 5 e mudar para 4

0 2 6 4 0

0 1 1 1 0

0 1 1 1 0

0 5 5 5 0

0 0 0 0 0

Repetir estes passos até ao fim

0 2 6 6 0

0 1 1 1 0

0 1 1 1 0

0 6 6 6 0

0 0 0 0 0

​Então como já estão todas as distancias para o ponto com valor 2 , mudava para 0 e pesquisava o próximo valor 6 e atribuia de novo o valor 2

0 0 2 6 0

0 1 1 1 0

0 1 1 1 0

0 6 6 6 0

0 0 0 0 0

Repetir o processo anterior mas desta vez o ponto de espera passa a ser o 5

0 0 2 5 0

0 1 1 1 0

0 1 1 1 0

0 5 5 4 0

0 0 0 0 0

repetir este processo até ter a matriz das distancias completa

Layout armazem

0 0 0 0 0

0 1 1 1 0

0 1 1 1 0

0 0 0 0 0

0 0 0 0 0

Matriz distancia

P1 P2 P3 P4 P5 P6

P1 0 1 2 5 6 7

P2 1 0 1 6 7 6

P3 2 1 0 7 6 5

P4 5 6 7 0 1 2

P5 6 7 6 1 0 1

P6 7 6 5 2 1 0

Algo assim deste genro.

Desculpa realmente estava muito confuso, penso que já se perceba melhor

	int xA=0, yA=0, xB=0, yB=4, i=0;


//atribuir pontos de picking (valor 5 significa que são picking em espera)
for(int y=0;y<m;y++){
  for(int x=0;x<n;x++){		
   if (map[x][y]==5){
map[x][y]=2;//passa a inicio
xA=x;
yA=y;
for(int y=0;y<m;y++){
  for(int x=0;x<n;x++){		
   if (map[x][y]==5){
map[x][y]=4;//passa a inicio
xB=x;
yB=Y;
// Informação a apresentar (Y,X)
  cout<<"Tamanho Armazem (X,Y): "<<n<<","<<m<<endl;
  cout<<"Inicio: "<<xA<<","<<yA<<endl;
  cout<<"Fim: "<<xB<<","<<yB<<endl;
  // obter a rota
  clock_t start = clock();
  string route=pathFind(xA, yA, xB, yB);
  if(route=="") cout<<"An empty route generated!"<<endl;
  clock_t end = clock();
  double time_elapsed = double(end - start);
  cout<<"Tempo de calculo de rota (ms): "<<time_elapsed<<endl;
  cout<<"Rota:"<<endl;
  cout<<route<<endl<<endl;

//#######################################################################################################################################################


  // siga a rota no mapa e exibi-lo
  if(route.length()>0)
  {
   int j; char c;
   int x=xA;
   int y=yA;
   map[x][y]=2;
   for(int i=0;i<route.length();i++)
   {
	   c =route.at(i);
	   j=atoi(&c);
	   x=x+dx[j];
	   y=y+dy[j];
	   map[x][y]=3;
   }
   map[x][y]=4;

   // mostrar o mapa com a rota
   for(int y=0;y<m;y++)
   {
	   for(int x=0;x<n;x++)
		   if(map[x][y]==0)
			   cout<<" ";
		   else if(map[x][y]==1)
			   cout<<"#"; //obstaculo
		   else if(map[x][y]==2)
			   cout<<"S"; //inicio
		   else if(map[x][y]==3)
			   cout<<"."; //rota
		   else if(map[x][y]==4)
			   cout<<"F"; //fim

	   cout<<endl;


   }
  }
map[xA][yA]=0;
map[xB][yB]=2;


}
}
}
}
}
}

Edited by maxfyre
Posted

não vou perguntar para que queres saber as "distâncias" entre os pontos determinados anteriormente (pontos de "interacção")

no entanto, uma pergunta é obvia olhando para essa explciação do que pretendes :

para que raio andas ai a alterar a torto e a direito o valor dos pontos, visto isso não serviro para nada ?

IRC : sim, é algo que ainda existe >> #p@p
Posted (edited)

Como posso fazer para ler um segundo ficheiro?

int main()
{

 // mapa em branco
for(int y=0;y<m;y++)
{
	for(int x=0;x<n;x++)
  map[x][y]=0;
}


//leitura do ficheiro com as coordenadas dos obstaculos
std::ifstream input("obstaculos.txt");
while (!input.eof())
{
	int xo, yo; // (x,y) dos obstaculos
	char separator; //virgula
	input >> xo  >> separator >> yo;
	for(int y=0;y<m;y++)
 {
	 for(int x=0;x<n;x++)
  map[xo][yo]=1;//atribui valor 1 para as coordenadas lidas
 }

}


/////////////////////////////////////////////////////////////////////////////////
////////////ERRO A LER OUTRO FICHEIRO - como posso ler um segundo ficheiro?//////
/////////////////////////////////////////////////////////////////////////////////



//leitura do ficheiro com as coordenadas dos pontos de picking
std::ifstream input("picking.txt");
while (!input.eof())
{
 int n=10;
	int xp, yp; // (x,y) dos pontos de picking
	char separator; //virgula
	input >> xp  >> separator >> yp;
	for(int y=0;y<m;y++)
 {
	 for(int x=0;x<n;x++)
  map[xp][yp]=5;//atribui valor 5 para as coordenadas lidas

 }

}

Edited by maxfyre

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.