» »

[C++] Delo z nizi

[C++] Delo z nizi

Ciklamen ::

Pozdravljeni fantje, opiram se nas ker upam da mi lahko kako pomagate.

Imam sledečo kodo, ki pa mi kot kaže ne deluje dobro, ker mi crash-a ko jo zaženem, upam da vi najdete kje napake (pomoje jih ni niti malo)

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

void steviloCrk(string niz) {
	int counter;
	for(int i=0; i<niz.length(); i++) {
        if((niz[i] >= 'a' && niz[i] <= 'z') || (niz[i] >= 'A' && niz[i] <='Z')) counter++;
    }
    cout<<counter;
}
void obrniNiz(string niz, int n) {
	if (niz[n] != '\0') { // &#232;e ni prazen niz
		obrniNiz(niz, n++);
		cout<<niz[n-1];
	}
}
void stetjeBesed(string niz) {
	int counter;
	for(int i=0; i<niz.length(); i++) {
        if(niz[i] == ' ' || niz[i] == '\n' || niz[i] == '\t' ) { // pogoj, &#232;e je znak presledek, nova vrsta ali tabulator
            counter++;
        }
	}
	cout<<counter;
}
void stetjeSicnikov(string niz) {
	int counter;
	for(int i=0; i<niz.length();i++) {
        if(niz[i] == 'c' || niz[i] == 's' || niz[i] == 'z') {
            counter++;
        }
    }
	cout<<counter;
}
void izbrisiLocila(string niz) {
	string novNiz;
	for(int i=0; i<niz.length(); i++) {
		if(niz[i] == '?' || niz[i] == '.' || niz[i] == ',' || niz[i] == '!' || niz[i] ==':' || niz[i] == ';') {
			continue;
		} else {
			novNiz[i] = niz[i];
		}
	}
	cout<<novNiz;
}
void kodiraj (string niz) {
	for (int i=0; i<niz.length(); i++) {
		niz[i]+= 1;
		cout<<niz[i];
	}
}
int main() {

	string niz = "Racunalnistvo je znanstvena veda o delovanju racunalnikov in o njihovi uporabi, \n"
			" kar vkljucuje strojno in programsko opremo. V praksi je racunalnistvo povezano z mnogimi \n"
			"drugimi vedami, od abstraktne analize algoritmov do bolj stvarnih tem, kot so programski jeziki, \n"
			"programska in strojna oprema.  Kot znanstvena veda se racunalnistvo loci od matematike, programiranja, \n"
			" programskega inzenirstva in racunskega inzenirstva, ceprav se ta podrocja pogosto zamenjujejo. \n";

    steviloCrk(niz);
    obrniNiz(niz, 0);
    stetjeBesed(niz);
    stetjeSicnikov(niz);
    izbrisiLocila(niz);
    kodiraj(niz);
}



Hvala že v naprej če se bo kdo spravil tega brati sploh :)
- End of the Post ->

darkkk ::

Prva stvar, ki jo opazim: tam kjer brišeš ločila, v nov niz na i-to mesto pišeš kar ni ločilo, ampak nov niz je krajši (in nasploh dostopaš do nečesa kar ne smeš), ker nov niz ni dovolj dolg.
Napako odpraviš tako, da novNiz += znak, kjer je pač znak, ki ga appendaš.

Drugače pa še, morda namesto stringa uporabljaj wstring, ter namesto char wchar_t (meni v VS2010 rešuje dosti preglavic).

Ciklamen ::

Vbistvu moram s stringom delat, in sedaj sem šel še enkrat skozi, sem opazil kakšne bedarije sem delal :P

void obrniNiz(string niz, int n) {
    if (niz[n] != '\0') { // &#232;e ni prazen niz
        obrniNiz(niz, n++);
        cout<<niz[n-1];
    }
}


sem zamenjal z

void obrniNiz(string niz) {
     for(int i=niz.length()+1; i >= 0; i--) {
          cout<<niz[i];
     }
}


ter tam kjer je brisanje ločil sem pomaknil izpis znotraj for zanke (ker mi v štartu ni nič izpisovalo). Sedaj zadeva deluje kot mora :) Aja pa še niz sem preoblikoval v eno samo vrstico, ne v več vrstic kot je v kodi :)
- End of the Post ->

klemen93 ::

V vsaki funkciji na začetku nastavi counter na 0.

int counter = 0;

smoke ::

Zakaj pa ne narediš celotne stvari objektno? To je vbistvu C koda, z manjšimi C++ feature-i. Pisanje takšne C++ kode je kot da greš v Pariz in tam ješ v McDonaldsu. :D Brezveze je, če ti jezik nekaj ponuja, ti pa tega ne izkoristiš.

Aja.. opazil sem napako v funkciji stetjeBesed. Funkcija sicer deluje ko je besedilo lepo urejeno. Ampak kaj pa če vpišeš takšen string: "Danes je lep dan." Ker povečaš counter takoj ko najdeš presledek, ti bo v tem primeru našlo toliko besed kot je predledkov, to pa seveda ni prav. Možna rešitev je recimo da gledaš še kateri znak je bil pred presledkom (ali line breakom ali tab-om), če ni bil presledek, line break ali tabulator, potem povečaš counter, drugače ne.

Pa še nekaj.. uporabljaj iteratorje (ali reverse iteratorje) za sprehajanje po stringu, bo koda malo lepše zgledala. Pravtako imaš metodo string::erase za brisanje znakov iz stringa.

Lep pozdrav!

mallard ::

Poglej si malo headerje algorithm, iterator, in cctype. Namesto dolgoveznega stavka
if((niz[i] >= 'a' && niz[i] <= 'z') || (niz[i] >= 'A' && niz[i] <='Z'))

bi naprimer lahko imel
if (isalpha(niz[i])

V funkciji
void obrniNiz(string niz) {
     for(int i=niz.length()+1; i >= 0; i--) {
          cout<<niz[i];
     }
}

bi moralo bit length()-1, drugače v prvih dveh iteracijah dostopaš izven meja niza. Funkcija bi bla se najbolj enostavna takole:
void obrniNiz(const string& niz)
{
    std::cout << string(niz.rbegin(), niz.rend());
}


Z uporabo headerja algorithm se lahko izogneš pisanju for-zank, pa še namen kode je bolje izražen. Jaz bi naprimer štetje besed napisal takole. Tako ti ni treba preverjat primerov na primer ko se niz začne s presledkom, ko je več presledkov en za drugim, itd.

#include <sstream>
#include <iterator>
#include <string>

size_t stetjeBesed(const std::string& niz)
{
    std::istringstream iss(niz);
    return std::distance(
               std::istream_iterator<std::string>(iss),
               std::istream_iterator<std::string>());
}

donkihod ::

Tole se mi zdi, da kr kliče po lambdah.
int sicniki = 0;
std::for_each(niz.begin(), niz.end(), [&sicniki](char c){
    if (c == 'c' || c == 's' || c == 'z')
        ++sicniki;
});

std::cout << "skupaj sicnikov: " << sicniki << "\n";

std::for_each(niz.begin(), niz.end(), [](int c){
    std::cout << char(c + 1);
});

Sicr pa v funkciji kodiraj je brezveze najprej povečat vrednost za 1 in pol izpisat, ker je klic po vrednosti in ne po referenci.

aljazko1995 ::

Jaz bi prosil samo da naj eden naredi program KRIŽCI IN KROŽCI

amacar ::

Ne bodi tečen, pa se spravi sam delat. Sicer pa imaš na netu 100 in 1 implementacij te igre, tako da pogooglaj, če se ti že delat ne da!

krneki0001 ::

Začni sam, ko boš prošel do problema pa napiši tukaj kodo in ti bomo pomagali naprej.
Asrock X99 Extreme 4 | Intel E5-2683V4 ES | 64GB DDR4 2400MHz ECC |
Samsung 250GB M.2 | Asus 1070 TI | 850W Antec | LC Tank Buster

krneki0001 ::

Tukaj imaš kodo v ruby-ju. Če poznaš kaj jezike, boš hitro naredil po tem kodo v c++.

Slot = Struct.new(:row, :column, :value)

# n x n polj
class Board
  X = "X"
  O = "O"
  attr_accessor :grid, :slots, :game_over, :current_player, :winner
  def initialize(n)
    @grid, @slots = Array.new(n), Hash.new 
    @game_over, @current_player, @winner = false, Board::X, nil
    slot_counter = 0
    @grid.each_with_index do |row, i|      
      @grid[i] = Array.new(n)
      @grid[i].each_with_index do |column, j|
        @grid[i][j] = Slot.new(i, j, slot_counter)
        @slots[slot_counter] = @grid[i][j]
        slot_counter += 1
      end
    end      
  end
  def draw
    system("clear")
    @grid.each_with_index do |row, i|
      row_print = row.collect{ |s| s.value }.join(" | ")
      puts row_print
      puts "-" * row_print.length if @grid.length != (i + 1)
    end
    puts ""
  end
  def move
    print "#{@current_player} -- Vpisi stevilko: "
    slot_number = gets.chomp.to_i
    if !@slots.has_key?(slot_number)
      move
    elsif @slots[slot_number].value == Board::X || @slots[slot_number].value == Board::O
      puts "Ze uporabljeno, vpisi drugo stevilo!"
      move
    else
      @board_updated = true
      @slots[slot_number].value = @current_player
    end
    if won?(@slots[slot_number])
      @game_over = true
      @winner    = @current_player
    elsif stalemate?
      @game_over = true      
    else
      switch_turn if @board_updated
    end
  end
  def switch_turn
    @current_player = (@current_player == Board::X) ? Board::O : Board::X
    @board_updated = false
  end
  def won?(slot)
     horizontal_win?(slot) || 
     vertical_win?(slot) || 
     diagonal_win?(:orientation => "l2r") || 
     diagonal_win?(:orientation => "r2l")
  end
  def stalemate?
    stalemate = true
    @slots.each { |k,slot| stalemate = false if slot.value.is_a?(Fixnum) }
    stalemate
  end
  def game_over?
    @game_over
  end
  private 
  def horizontal_win?(slot)
    slot_values = @grid[slot.row].collect{ |s| s.value == @current_player }
    slot_values.length == @grid.length && slot_values.uniq.to_s == "true"
  end
  def vertical_win?(slot)
    slot_values = @grid.collect{ |r| r[slot.column] }.collect{ |s| s.value == @current_player }
    slot_values.length == @grid.length && slot_values.uniq.to_s == "true"
  end
  def diagonal_win?(options = {})
    slots = []    
    case options[:orientation]
      when "l2r" then 0.upto(@grid.length - 1) { |i| slots << @grid[i][i]  } 
      when "r2l" then (@grid.length - 1).downto(0){ |i| slots << @grid[i][@grid.length - 1 - i] }
    end
    slot_values = slots.collect { |s| s.value == @current_player }
    slots.length == @grid.length && slot_values.uniq.to_s == "true"
  end

end

board = Board.new(3)
while !board.game_over? do 
  board.draw
  board.move
end
board.draw
puts !board.winner.nil? ? "#{board.winner} Won!" : "The game was a draw!"
Asrock X99 Extreme 4 | Intel E5-2683V4 ES | 64GB DDR4 2400MHz ECC |
Samsung 250GB M.2 | Asus 1070 TI | 850W Antec | LC Tank Buster


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Niti - segmentation fault

Oddelek: Programiranje
211973 (820) galu
»

[C++] charset-a

Oddelek: Programiranje
7898 (755) SasoS
»

[C] Narascajoce sortiranje linearnega seznama

Oddelek: Programiranje
71857 (1746) Jebiveter
»

ena funkcija oz. progic v c-ju

Oddelek: Programiranje
5980 (811) noraguta
»

štetje vpisanih znakov

Oddelek: Programiranje
81356 (1269) bostek

Več podobnih tem