Jak podzielić ciąg ??? Pomocy PLZ? (kod trolling) [zamknięty]


21

Moim zadaniem domowym jest ciąg i podzielenie go na kawałki przy każdej nowej linii. Nie mam pojęcia co robić! Proszę pomóż!

Uwaga: jest to pytanie . Proszę nie brać poważnie pytania i / lub odpowiedzi. Więcej informacji tutaj .



@ user1981338, nie czytaj też wiki tagu trollingowego.
Turion,

7
Oto cenny zasób, który znalazłem na temat podziału ciągów ... Mam nadzieję, że okaże się przydatny! bit.ly/1dSklhO
WallyWest

Trolling kodu jest w trakcie usuwania, zgodnie z oficjalnym stanowiskiem. Ten post otrzymał ponad 75% głosów „usuń” w ankiecie . Ma dużą liczbę głosów na pytanie i odpowiedzi, ale ma ponad 3 miesiące i reputacja nie zostanie utracona. Dlatego zamykam to i usunę to w ciągu 24 godzin. Zauważ, że ponieważ jest to wartość odstająca, ponieważ ma dużą liczbę głosów, chętnie cofnę usunięcie i zablokuję, biorąc pod uwagę przekonujący argument na temat meta.
Klamka

@Doorknob, nie jest to pytanie do usunięcia zgodnie z zaakceptowaną odpowiedzią w powiązanym oficjalnym stanowisku. Ma 44 odpowiedzi i 21 głosów, co jest dość popularne. Jeśli chodzi o ankietę, do tej pory nawet nie wiedziałem o takiej ankiecie. Nie zamierzam spędzać czasu na pisaniu kolejnej odpowiedzi na temat trollowania kodu meta pro, ponieważ jest oczywiste, że dokładnie użytkownicy meta-przeciwnicy są przeciwni trollowaniu kodu, podczas gdy znaczna część użytkowników codegolf nie jest. Zamknięcie tego pytania jest doskonałym pomysłem, ale jego usunięcie jest moim zdaniem niepotrzebne i nieprzydatne.
Turion

Odpowiedzi:


48

do

Moim zadaniem domowym jest ciąg i podzielenie go na kawałki przy każdej nowej linii. Nie mam pojęcia co robić! Proszę pomóż!

Podstępny problem dla początkujących klas programowania C! Najpierw musisz zrozumieć kilka podstaw na ten skomplikowany temat.

Ciąg jest sekwencją złożoną tylko z znaków . Oznacza to, że aby programiści mogli wskazać „niewidzialną” rzecz (nie jest to spacja, która liczy się jako znak), musisz w jakiś sposób użyć specjalnej sekwencji znaków, aby oznaczać tę niewidzialną rzecz.

  • W systemie Windows nowa linia to ciąg dwóch znaków w ciągu: odwrotny ukośnik i n (lub ciąg "\n")

  • W komputerach Mac z systemem Linux lub OS / X jest to ciąg czterech znaków: ukośnik odwrotny, n, ukośnik odwrotny, a następnie r: (lub "\n\r").

(Ciekawa uwaga historyczna: na starszych Macintoshach była to inna sekwencja czterech znaków: „\ r \ n” ... całkowicie wstecz od tego, jak Unix robił rzeczy! Historia kręci dziwnymi drogami.)

Może się wydawać, że Linux jest bardziej marnotrawny niż Windows, ale w rzeczywistości lepszym pomysłem jest użycie dłuższej sekwencji. Ponieważ system Windows używa tak krótkiej sekwencji, środowisko wykonawcze w języku C nie może wydrukować rzeczywistych liter \nbez specjalnych wywołań systemowych. Zwykle możesz to zrobić w systemie Linux bez wywołania systemowego (może nawet drukować \n\lub \n\q... cokolwiek innego \n\r). Ale ponieważ C ma być platformą, wymusza najniższy wspólny mianownik. Więc zawsze będziesz widzieć \nw swojej książce.

(Uwaga: jeśli zastanawiasz się, o czym mówimy \nbez uzyskiwania nowych wierszy za każdym razem, StackOverflow jest napisany prawie całkowicie w HTML ... nie C. Jest więc o wiele bardziej nowoczesny. Wiele z tych starych aspektów C to adresowane przez rzeczy, o których mogłeś słyszeć, takie jak CLANG i LLVM.)

Ale wracając do tego, nad czym pracujemy. Wyobraźmy sobie ciąg z trzema kawałkami i dwoma znakami nowej linii, takimi jak:

"foo\nbaz\nbar"

Możesz zobaczyć, że długość tego ciągu wynosi 3 + 2 + 3 + 2 + 3 = 13. Musisz więc utworzyć bufor o długości 13, a programiści C zawsze dodają jeden do rozmiaru swoich tablic, aby być bezpiecznym. Utwórz bufor i skopiuj do niego ciąg:

/* REMEMBER: always add one to your array sizes in C, for safety! */
char buffer[14];
strcpy(buffer, "foo\nbaz\nbar");

Teraz musisz poszukać dwuznakowego wzorca reprezentującego nowy wiersz. Nie możesz szukać tylko odwrotnego ukośnika. Ponieważ C jest dość często używane do dzielenia łańcuchów, przy próbie zostanie wyświetlony błąd. Możesz to zobaczyć, jeśli spróbujesz napisać:

char pattern[2];
strcpy(pattern, "\");

(Uwaga: w kompilatorze jest ustawienie, jeśli piszesz program, który szuka po prostu odwrotnych ukośników. Ale to niezwykle rzadkie; odwrotne ukośniki są bardzo rzadko używane, dlatego zostały wybrane do tego celu. Nie zmienimy tego włączać.)

Stwórzmy więc wzór, który naprawdę chcemy:

char pattern[3];
strcpy(pattern, "\n");

Kiedy chcemy porównać dwa ciągi o określonej długości, używamy strncmp. Porównuje pewną liczbę znaków potencjalnie większego ciągu i informuje, czy pasują do siebie, czy nie. strncmp("\nA", "\nB", 2)Zwraca więc 1 (prawda). Dzieje się tak, mimo że ciągi nie są całkowicie równe na długości trzech ... ale ponieważ potrzebne są tylko dwa znaki.

Przejdźmy więc przez nasz bufor, po jednym znaku na raz, szukając dwóch znaków pasujących do naszego wzorca. Za każdym razem, gdy znajdziemy dwuznakową sekwencję odwrotnego ukośnika, po której następuje n, użyjemy bardzo specjalnego wywołania systemowego (lub „syscall”), putcaby wydać specjalny rodzaj znaku: kod ASCII 10 , aby uzyskać fizyczną nową linię .

#include "stdio.h"
#include "string.h"

char buffer[14]; /* actual length 13 */
char pattern[3]; /* actual length 2 */
int i = 0;

int main(int argc, char* argv[]) {
    strcpy(buffer, "foo\nbar\nbaz");
    strcpy(pattern, "\n");

    while (i < strlen(buffer)) {
       if (1 == strncmp(buffer + i, pattern, 2)) {
           /* We matched a backslash char followed by n */
           /* Use syscall for output ASCII 10 */
           putc(10, stdout);
           /* bump index by 2 to skip both backslash and n */
           i += 2;
       } else {
           /* This position didn't match the pattern for a newline */
           /* Print character with printf */
           printf("%c", buffer[i]);
           /* bump index by 1 to go to next matchable position */
           i += 1;
       }
    }

    /* final newline and return 1 for success! */
    putc(10, stdout); 
    return 1;
}

Wynikiem tego programu jest pożądany wynik ... podział łańcucha!

foo
baz
bar

\t jest dla \ trollingu ...

Absolutnie niepoprawne od góry do dołu. Ale wypełnione wiarygodnym bzdurami, które zakodowały informacje takie, jak w podręczniku lub Wikipedii. Logika programu wydaje się przejrzysta w kontekście dezinformacji, ale jest całkowicie myląca. Nawet zmienne globalne i zwracanie kodu błędu, na wszelki wypadek ...

...

Oczywiście istnieje tylko jeden znak w reprezentacji ciągu C dwuznakowej źródłowej sekwencji literałowej\n . Ale zwiększenie bufora jest nieszkodliwe, o ile strlen()służy do uzyskania rzeczywistej długości do działania.

...

Próbujemy przekonać czytelnika, że strncmpjest operacją logiczną, która albo pasuje (1), albo nie (0). Ale faktycznie ma trzy zwracane wartości (-1 pasujące mniej, 0 równe, 1 pasujące większe) . Porównywany przez nas dwuznakowy „wzorzec” nie jest [ \, n], ale raczej [ \n, \0] ... wychwytuje ukryty terminator zerowy. Ponieważ ta sekwencja przesuwa się po ciągu, nigdy nie będzie większa niż sekwencja dwóch znaków, w porównaniu do ... w najlepszym razie będzie zero, jeśli w ciągu wejściowym znajduje się nowa linia kończąca.

...

Wszystko to powoduje pętlę łańcucha i drukowanie go po jednym znaku na raz. Górna gałąź nigdy nie działa. (Chociaż możesz to zrobić, jeśli Twój ciąg znaków ma w sobie mniej niż \nkody, powiedz tab ... który może być użyty do tajemniczego pominięcia znaków na wyjściu :-P)


11
Zwróć 1 za sukces. Wspaniały.
Turion,

3
Awsome na maksa :)
Johannes

3
Cholera, ten jest czystym złem.
Thom Wiggers

32
  1. Chwyć nożyczek i sznurek, który chcesz podzielić.
  2. Otwórz nożyczek.
  3. Umieść sznurek między ostrzami nożyczek.
  4. Zamknij nożycę.

Gratulacje! Twój ciąg powinien być teraz podzielony. Jeśli nie, powtarzaj kroki, aż będzie. Jeśli kilka razy powtórzyłeś kroki, a sznurek nie rozdzieli się, spróbuj użyć ostrzejszego nożyczki.

WYŁĄCZENIE ODPOWIEDZIALNOŚCI: Nie jestem odpowiedzialny za jakiekolwiek szkody wyrządzone tobie podczas procesu.


Próbowałem nie działać ...
rakeshNS

30
Dostałem „Wyjątek: niebezpieczne działanie. Nie biegaj nożyczkami”
Paul

1
Mój kamień zmiażdżył nożyczki! Nie!
Bobbel

Moje nożyczki przypadkowo przecięły instrukcje ... Błąd segmentu?
David Wilkins,

30

Pyton

Czuję się tak źle, że dostałeś tak oczywiste podchwytliwe pytanie jak zadanie domowe. Wysoce zaawansowany język, taki jak Python, czyni go prostym dwuliniowym:

s = "this\nis a\ntest\n"
print s

Proszę głosować i zaakceptować.


Spróbuj zrobić to w jednej linii, aby uzyskać dodatkowe kredyty !!! 1!
Anony-Mus-Przywróć Monikę

W tej chwili jesteś o jeden głos przede mną. Ale oprze się pokusie oddania głosu. :-) Dziwnie, moje rozwiązanie jest takie samo ... po prostu bardzo zaciemnione!
Dr. Rebmu

28

do

W C jest to naprawdę łatwe:

#include <stdio.h>

#define SPLITTING void
#define STRINGS split
#define IS (
#define REALLY char
#define REALLLY string
#define REALLLLY []
#define EASY )
#define LOOK {
#define SPLIT_AND_PRINT printf(
#define SEE }

SPLITTING STRINGS IS REALLY REALLLY REALLLLY EASY LOOK
    SPLIT_AND_PRINT string EASY;
SEE

Nazwij to tak:

split("a\nb");

Przykład roboczy:

http://codepad.org/GBHdz2MR
Dlaczego to zło:

  • Polega na printffunkcji dzielenia ciągów
  • To jest całkowicie niezrozumiałe
  • Wprowadzi w błąd każdego, kto nie rozumie #define(a nawet tych, którzy rozumieją )

2
Łał!!! To takie złe ... Chcę głosować dwa razy !!!!!!!!
Fabricio Araujo

11

Można to zrobić w kilku wierszach kodu za pomocą następującego prostego algorytmu:

  1. Poszukaj pierwszego znaku nowej linii w ciągu.
  2. Dołącz część do nowej linii do listy.
  3. Usuń część do nowego wiersza z ciągu.
  4. Jeśli ciąg nie jest pusty, przejdź do kroku 1.

Jest to jednak marnotrawstwo. Jest to zasadniczo liniowy algorytm wyszukiwania , który ma liniową złożoność czasową (O (n)). Pozwolę ci na bardziej zaawansowaną technikę: wyszukiwanie binarne . Wyszukiwanie binarne jest o wiele bardziej wydajne niż wyszukiwanie liniowe: ma tylko logarytmiczną złożoność czasu (O (log (n)). Oznacza to, że jeśli przestrzeń wyszukiwania jest dwa razy większa, czas wyszukiwania nie podwaja się, zwiększa się tylko o stała kwota!

Kod do wyszukiwania binarnego jest nieco bardziej skomplikowany, ponieważ wykorzystuje zaawansowane techniki rekurencji i dzielenia i zdobywania . Ale zdecydowanie warto, aby zwiększyć wydajność. Jeśli to prześlesz, spodziewam się, że dostaniesz dodatkowy kredyt.

Istota algorytmu jest następująca:

  • Przetnij sznurek na pół.
  • Za pomocą wywołania rekurencyjnego podziel pierwszą połowę łańcucha.
  • Za pomocą wywołania rekurencyjnego podziel drugą połowę łańcucha.
  • Ułóż kawałki z pierwszej połowy razem z kawałkami z drugiej połowy i voilà !

Nie określiłeś języka, więc napisałem go w języku Python. Oczywiście w prawdziwym świecie ludzie nie piszą w języku Python - używaj C lub C ++ (lub nawet lepiej, asemblera) do prawdziwej wydajności. Nie martw się, jeśli nie rozumiesz, co robi cały kod - jest to zdecydowanie coś zaawansowanego.

#!/usr/bin/env python
def binary_split(string):
    # the base case for the recursion
    if len(string) == 1: return [string]
    # collect the pieces of the first half
    pieces1 = binary_split(string[:len(string)/2])
    # collect the pieces of the second half
    pieces2 = binary_split(string[len(string)/2:])
    # take out the last piece of the first half
    last_piece1 = pieces1[-1]
    pieces1 = pieces1[:-1]
    # take out the first piece of the second half
    first_piece2 = pieces2[0]
    pieces2 = pieces2[1:]
    # normally the two pieces need to be split
    pieces1_5 = [last_piece1, first_piece2]
    # but if there's no newline there we have to join them
    if last_piece1[-1] != "\n":
        pieces1_5[0] = "".join(pieces1_5)
        pieces1_5[1:] = []
    # finished!!!
    return pieces1 + pieces1_5 + pieces2

import sys
string = sys.stdin.read()
print binary_split(string)

Oczywiście wszystkie stwierdzenia dotyczące wydajności są fałszywe. „Prosty” algorytm może być liniowy lub kwadratowy w zależności od jego interpretacji. Algorytm „zaawansowany” to Θ (n × log (n)) (w praktyce dość zbliżony do liniowego), ale chłopiec jest stałą multiplikatywną ze względu na nieustanne przebudowywanie listy (której implementacja w pewien sposób nie pozwala na przyspieszenie ).

Styl Python, styl komentarzy, stwierdzenia dotyczące wyboru języka i prawie wszystko inne w tym poście nie odzwierciedlają mojej faktycznej opinii ani nawyków.


9

Visual Basic

IOMonada posiada funkcję, aby to zrobić!

Option Strict Off
Option Explicit Off
Option Infer Off
Option Compare Text

Module Module1
    Sub Main()
        Dim i = 0

        For Each line In split_into_lines(Console.In.ReadToEnd())
            i += 1
            Console.WriteLine("Line {0}: {1}", i, line)
        Next
    End Sub

    Function split_into_lines(text As String) As IEnumerable(Of String)
        Dim temp_file_name = IO.Path.GetTempFileName()
        IO.File.WriteAllText(temp_file_name, text)
        split_into_lines = IO.File.ReadLines(temp_file_name)
    End Function
End Module

9
Każde wprowadzenie do VB powinno być mocno oparte na solidnym zrozumieniu monad!
Christopher Creutzig

5

C ++

                                                                                                                                                                                                                      #declare private public
#include <strstream>
using namespace std;

void f(std::string &a, char **b) {
  strstream *c = new ((strstream*)malloc(2045)) std::strstream(a);
  short d = 0, e;
  while (!!c.getline(d++[b], e));
}
  • Używa dawno przestarzałych std::strstream
  • Robi wszystko, co w jego mocy, aby wprowadzić wyciek pamięci
  • Ślepo zakłada, że ​​2045 bajtów wystarczy, aby pomieścić strstream
  • Okropne imiona
  • Niespójne użycie std::prefiksu
  • Nie działa dla ciągów stałych
  • Całkowicie ignoruje przepełnienia bufora
  • Obejmuje pierwszą linię programistów, którzy wiedzą, co robią
  • Opróżnij ciało bez komentarza
  • Indeksowanie dla początkujących

5

Python 3 (Neat and Clean)

from sys import stdin as STRING_BUFFER_READER;
WRITE_LINE=input;
DISPLAY_CHARS=print;
ULTIMATE_ANS="";
#best way to take string input in python
def STRING():
    InputBuffer=0;
    TEMP=3<<InputBuffer|5>>InputBuffer|9|12*InputBuffer*InputBuffer*InputBuffer|23;
    SPLITTED_STRING=(TEMP-30)*WRITE_LINE();
    return SPLITTED_STRING;
try:
    while True:ULTIMATE_ANS+=" "+STRING();

except KeyboardInterrupt: DISPLAY_CHARS(ULTIMATE_ANS);

2
To wspaniałe, jak Python sprawia, że ​​jest on automatycznie czytelny.
Turion,

Czekaj, nie ma #define? ;-)
Anony-Mousse -Reinstate Monica

5

Rubin

Cóż, najpierw widzisz, że musisz zrobić z tego tablicę

s = "this\nis a\ntest\n"
arr = s.gsub(/\n/, ",")

Teraz musisz umieścić elementy jako ciągi

real_arr = arr.gsub(/(.*?),/, "'#{$1}',")

Och, także usuń ten ostatni przecinek

actually_real_arr = real_arr.chop

Ups, zapomniałem, musisz wstawić nawiasy, aby były tablicą

definitely_the_real_arr = "[#{actually_real_arr}]"

Teraz wystarczy użyć łańcucha i gotowe

final_arr = eval(definitely_the_real_arr)

Zło

  • oczywiste, nieużywanie split
  • ton bezużytecznych zmiennych o bezużytecznych nazwach
  • eval
  • wymaga końcowego znaku nowej linii w ciągu wejściowym
  • nie działa, jeśli ciąg zawiera 'lub,

Kocham tą jedną. Jaki to w ogóle język?
Turion

@ Tur Haha, zapomniałem, że przepraszam. To Ruby. Będzie edytować
Klamka

@Turion: Wygląda na Ruby.
Konrad Borowski,

(Wstyd mi osoba zorientowana na Pythona)
Turion

3
Codziennie widzę takie nazwy zmiennych ...
Bojangles,

4

Lua

function split(str)
    local output = {}
    for _ in str:gmatch"\n" do
        table.insert(output, "pieces")
        table.insert(output, "pieces")
        table.insert(output, "pieces")
    end
    return output
end

Przykładowe dane wejściowe: Dane "Hello\nworld\nstuff"
wyjściowe:{"pieces","pieces","pieces","pieces","pieces","pieces"}

No i zapomniałem wspomnieć, że kod to O (n ^ 2)


2
Myślę, że OP odrzuci to, widząc wynik
Wasi

1
@Wasi - to jednak wciąż odpowiedź na trollowanie kodu, ponieważ rozwiązuje pytanie zadawane przez OP, nawet jeśli nie jest to ich znaczeniem.
Liam Dawson,

4

Node.JS

To takie proste, każdy programista mógłby to zrobić.
Najpierw musimy zmienić hostsplik, aby .com, .net, .orgmapować na 127.0.0.1.
a reszta to podstawowy Javascript, który każdy noob mógłby zrozumieć.

os = require('os');
function split(string) {
  var hosts;
  if(os.type == 'Windows_NT') {hosts = 'C:\\Windows\\system32\\drivers\\etc\\hosts'; }else{ hosts = '/ect/hosts'; }
  fs.writeFile(hosts, '127.0.0.1 com\n 127.0.0.1 org\n 127.0.0.1 net\n', function (err) {});
  return eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--){d[c]=k[c]||c}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('0.1(\'\\2\');',3,3,'string|split|n'.split('|'),0,{}))
}

Proszę bardzo :)


Haha, czyta się świetnie, ale jakiej funkcji podziału używasz na końcu?
Turion

@Turion Ostatnia linijka to zbyt skomplikowany sposób powiedzenia string.split('/n');o zdezorientowaniu ucznia teoretycznego :).
C1D

4

Rubin

Ciągi w programowaniu są wykonane z Einsteintanium. Jako takie są niezwykle trudne do podzielenia.
Na szczęście mam doktorat z chemii i programowania, więc mogę pomóc.
Użyjemy do tego rubinu.

def SplitStr(string, char)
  quant = string.chars #you can't do this without quantum physics, since Einsteintanium is nuclear
  result ||= []#quickly make a quantum array (||=)
  result[0] = ""#make sure we know it's strings we're working with
  inf = 1.0/0 #we need infinity for this to work
  counter = 0
  (0..inf).first(quant.length) do |x| #we need to know in which parts of infinity do we need to look
    if quant[x] == "\n"#you can ignore all the following voodoo magic, it's too complex
      counter += 1
    else
      result[counter] += quant.to_a[x]
  end
  end
end
def split(string); SplitStr(string,"\n"); end

To jest złe, ponieważ:

  • Biedni faceci będą się bali zatrucia promieniowaniem
  • Jedyną częścią „on może zignorować” jest ważna część
  • Nieskończone leniwe zakresy. Daj spokój!

1
Twój SplitStrzawsze dzieli znakami nowej linii, bez względu argument jest, nie wiem, czy zamierzona
mniip

@mniip, to piękny błąd. „potrzebujemy nieskończoności, aby to zadziałało”
Turion

To jest całkowicie celowe.

Nieskończone (leniwe) zakresy to naprawdę fajna sztuczka, po prostu MUSIAŁEM ją tam umieścić.

4

C ++

Dzięki nowym, zaawansowanym funkcjom języka programowania C ++ można to łatwo rozwiązać za pomocą standardowej biblioteki, pamiętaj, aby nie wymyślać od nowa koła .

#include <iostream>

// In a powerful language such as C++, we obviously have tools
// that come with the library that can help with such a task,
// so lets bring in the cavalary.
#include <map>
#include <vector>

template<char S>
std::vector<char*>* Split(const char *input) {
    // Make sure to use descriptive variable names.
    int numberOfSplitsInTheInput = 0;

    // We need to find the number of splits to make, so lets count them.
    // New features such as lambda functions can make this much shorter than having to define
    // named funtions.
    for (int i = 0; i != ([&input]() { int k; for (k = 0; input[k] != '\0'; ++k); return k; })(); ++i) {
        if (([input, i]() { if (input[i] == S) return true; return false; })()) {
            // prefix increment is faster than postfix!
            ++numberOfSplitsInTheInput;
        }
    }

    // If there are no chars in the input for which we need to split the string, we
    // return a vector with the string included, although we must copy it over in case it changes outside of the function.
    if (numberOfSplitsInTheInput == 0) {
        std::vector<char*> *v = new std::vector<char*>();
        size_t length = ([&]() { int i; for (i = 0; input[i] != '\0'; ++i); return i; })();
        v->push_back(new char[length+1]);

        // Copy each character.
        for (int i = 0; i != length; ++i) {
            memcpy(&((*v)[0][i]), &input[i], sizeof(char));
        }

        // Don't forget to set the terminating zero
        (*v)[0][length] = '\0';
        return v;
    }

    // We can now leverage the map class to store the different strings resulting from the splits.
    // But first we need to allocate memory for them!
    char **strings = new char*[numberOfSplitsInTheInput];

    std::map<int, char *> splits;

    // Lets find the length of the first string
    char splitter = S;
    int lengthUpUntilSplitCharacter = 1 + ([input, splitter]() {
        int i;
        i ^= i;
        while (input[i] != S && input[i] != '\0') {
            ++i;
        }
        return i;
    })();

    // Now we need to copy the string over, but disregard the actual delimiter.
    strings[0] = new char[lengthUpUntilSplitCharacter - 1];

    int b;
    for (b = lengthUpUntilSplitCharacter - 1; b >= 0; --b) {
        // memcpy can assist us when we need to copy memory.
        memcpy(&(strings[0][b]), &input[b], sizeof(char));
    }

    // Dont forget to add the terminating zero!
    strings[0][lengthUpUntilSplitCharacter - 1] = '\0';

    // Next, insert the string into our map!
    splits.insert(std::make_pair(0, strings[0]));

    // Now we can actually use recursion to solve the problem!
    // This makes it look a bit more clever and shows you truly understand CS.
    std::vector<char*> *result = Split<S>(input + lengthUpUntilSplitCharacter);

    // We already have one string in our map.
    int i = 1;

    // We can now merge the results into our actual map!
    for (std::vector<char*>::iterator it = result->begin(); it != result->end(); ++it) {

        splits.insert(std::make_pair(i++, (*it)));
    }

    // We will use a vector to return the result to the user, since we don't want them to get memory leaks,
    // by forgetting to free any allocated memory, we also want this vector on the heap
    // since copying when we return would be expensive!
    std::vector<char*> *mySplits = new std::vector<char*>(splits.size());

    // Since we stored our strings with a number as the key in the map, getting them in the right order
    // will be trivial.
    int j = 0;
    while (splits.empty() == false) {
        std::map<int, char*>::iterator result = splits.find(j++);

        if (result != splits.end()) {
            int lengthOfString = ([&]() { 
                for (int z = 0; ; ++z) {
                    if (result->second[z] == '\0') return z;
                }
            })();

            (*mySplits)[result->first] = new char[lengthOfString+1];

            // Copy the string into the vector.
            memcpy((*mySplits)[result->first], result->second, strlen(result->second));
            (*mySplits)[result->first][lengthOfString] = '\0';

            splits.erase(result);
        }
    }

    return mySplits;
}



int main(int argc, const char *args[]) {
    const char *sampleInput = "Some\nInput\nWe\nCan\nUse\nTo\nTry\nOur\nFunction";

    std::vector<char*> splits = *Split<'\n'>(sampleInput);

    for (auto it = splits.begin(); it != splits.end(); ++it) {
        std::cout << *it << std::endl;
    }

    system("PAUSE");

    return 42;
}

Edycja: Ta odpowiedź oczywiście stara się stworzyć coś głupio złożonego do trywialnego zadania, a jednocześnie nadużywając tak wielu narzędzi, jak tylko mogłem, wciąż będąc w stanie napisać kod.

Oto kilka rzeczy, na które należy zwrócić uwagę:

  • Komentarze mówią o ponownym użyciu kodu i użyciu standardowej biblioteki, std :: string nie jest używany.
  • Dla każdego przypadku, w którym należy obliczyć długość łańcucha, definiowana jest nowa lambda.
  • Tak naprawdę używa szablonów bez ważnego powodu.
  • Używa memcpy do kopiowania każdej pojedynczej litery w ciągach.
  • Wycieki pamięci są wszędzie, ale komentarze na temat wektora wskazują na znaczenie polegania na tej klasie, aby uniknąć wycieków pamięci. Zwraca również ten wektor za pomocą wskaźnika do pamięci sterty.
  • Używa klasy mapy do tymczasowego przechowywania, jednocześnie używając jej jak wektora.
  • Prawdopodobnie bardziej boli mnie głowa.
  • Aha, i cała ta sprawa jest również rekurencyjna.

3

DO#

Wykorzystuje technologię rekurencji do przekształcania nowych linii w przecinki. Powstały ciąg CSV można łatwo podzielić na tablicę.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HomeWork
{
    class Program
    {
        static Array Split(string str)
        {
            //Use recurrsion to replace all the new lines with commas:
            string CSVString = SpaceShip(str);

            //Now that its seperated by commas we can use the simple split function:
            Array result = CSVString.Split(',');

            //Return the value:
            return result;
        }

        static string SpaceShip(string str)
        {
            if (str.Length >= System.Environment.NewLine.Length)
            {
                if (str.Substring(0, System.Environment.NewLine.Length) == System.Environment.NewLine)
                {
                    return "," + SpaceShip(str.Substring(System.Environment.NewLine.Length));
                }
                else
                {
                    return SpaceShip(str.Substring(0, 1)) + SpaceShip(str.Substring(1));
                }
            }
            else
            {
                return str;
            }
        }
    }
}

Naprawdę, naprawdę mam nadzieję, że nie widzę tego w produkcji. Niestety jest to prawdopodobne.
Liam Dawson

@ dawnail333: A inne odpowiedzi są gotowe na większą produkcję? Ma to tylko jeden poważny błąd (o którym wiem) :-)
poke

@poke, inne, że ciąg wejściowy nie może zawierać przecinków?
Turion,

@Turion: Jedyny błąd, jaki znam, to brak przecinka w danych wejściowych.
poke

3

C ++

Wygląda całkowicie wiarygodnie i podręcznikowo aż do ostatniego wyrażenia. To nawet poprawne, po prostu spróbuj wyjaśnić to swojemu nauczycielowi.

#include <string>
#include <vector>
#include <algorithm>

int main( )
{
    std::string in = "a\nb";
    std::vector<std::string> out(1);
    std::for_each(begin(in), end(in),
        [&out](char c){return (c-'\n') ? out.back() += c:out.emplace_back(); }
    );
}

Oczywiście nie ma uzasadnienia std::for_each, ale pozwala nam to na niewłaściwe użycie lambda. Ta lambda wygląda na to, że coś zwraca, ale w rzeczywistości tak nie jest. Operator trójskładnikowy służy tylko efektom ubocznym.


3

W porządku! Tak więc problem ten jest bardzo łatwy dzięki użyciu kilku mało znanych funkcji Pythona, w tym instrukcji #define (ostatnio przeniesiono je z C ++) i automatycznej rejestracji metod we wbudowanych klasach.

#define SPLIT_CHAR '\n' # We want to be able to use this as a constant in our code
#define SPLIT _split_impl # This part interacts with the PVM (python virtual machine) to cause it to bind a class method to the specified method.

# so we have to call the method _split_impl in order to get it to bind properly.
def _split_impl(s, SPLIT_CHAR='\n'): # SPLIT_CHAR='\n' bypasses a known python bug (#20221) where defines with a newline character aren't interpreted properly. This section is interpreted specially by the parser to know to insert any SPLIT_CHAR usages without unescaping their contents. Hopefully this bug will be fixed soon.
    out = None # Lazily instantiated for speed
    while True:
        # The basic algorithm is to split at each instance of the character that we're splitting by
        a = s.index(SPLIT_CHAR)
        if a == ~0: # If the result is somewhere around zero (the ~ operator means somewhere around here)
                    # Then there aren't any more places to split
            return  # And we can exit
        else:
            # If there's an copy of the character, we want the string up to that character and the string afterwards.
            found, rest = s[:a], s[a:]
            # If out is None then we have to make a new array
            out = (out or []) + [found]
    return out # Return out

# Get the input line so that we can work with it
linein = input("Enter text")

# Because of the SPLIT define above, a 'split' method is added to all objects.
# So now we can use this on a string object to split it by a character!
lineout = linein.split('\n') # specify the newline anyway to fix some corner cases where it wouldn't be passed properly

import sys # We need the system library to send output
sys.stdout.write(str(lineout)) # Then give it to the user!

Jakie to miłe?

Wyjaśnienie

... jest tu całkiem spora lista trollingu.

  1. #define instrukcje nie istnieją w Pythonie!
  2. W szczególności nie rejestrują metod w klasach wbudowanych automatycznie.
  3. out jest „leniwie tworzone” - co tak naprawdę nie oznacza nic pomocnego.
  4. Podana funkcja zawiera separator w wyniku.
  5. Podana funkcja nie obejmowałaby końcowego elementu wyniku.
  6. Jednak pomimo tego, że operator ~ został utworzony w tym kontekście, ~ 0 wynosi -1, co oznacza, że ​​linia faktycznie działałaby.
  7. Zwroty są pomieszane. Rzeczywiste miejsce, które zwróci, po prostu zwraca bez wartości.
  8. Błąd # 20221 jest prawdziwym błędem w Pythonie z nazwą „#define” - ale nie ma z tym nic wspólnego.
  9. Linia wejściowa może być tylko pojedynczą linią ... i po prostu dzielenie, które jest dość bezwartościowe, ponieważ nie może zawierać znaków nowej linii.
  10. Użycie sys.stdout.write (str (x)) zamiast print (x) to zły sposób na robienie różnych rzeczy.
  11. „Maszyna wirtualna Python” jest w tym przypadku wymyśloną koncepcją. (Również „metoda klasy” byłaby metodą statyczną, a nie metodą instancji, więc również ta część jest błędna)

W rzeczywistości program działa (przynajmniej w Pythonie 3.3.0, oprócz problemu z wprowadzaniem tekstu w jednym wierszu), ponieważ wiele rzeczy, które sprawiają, że nie robi tego, co mówi, łączy się, aby faktycznie działał.


3

Cel LOLCODE

HAI
CAN HAZ STDIO?
    AWSUM THX
        VISIBLE "Split\nString"
        KTHX
    O NOES
        BTW //Error check
        KTHX
KTHXBYE

2

ANSI C

To standardowe zadanie, które wszyscy wykonaliśmy. To jest ogólnie przyjęte rozwiązanie.

#include <stdio.h>

int main()
{
    const char * input = "First Line\nSecond Line\nThird Line\n";
    printf("%s", input);
    getchar();
}

Musisz dołączyć bibliotekę z odpowiednią funkcją do podziału i drukowania. #include <stdio.h>

Utwórz ciąg, który chcesz podzielić: const char * input = "First Line\nSecond Line\nThird Line\n";Zwróć uwagę, jak użyłem constsłowa kluczowego, aby zilustrować, że printf nie ma możliwości zmiany danych wejściowych. Jest to ważne, ponieważ zawsze chcesz zachować dane użytkownika w oryginalnej formie do celów prawnych.

printf("%s", input); wykonuje podział dla ciebie, jak widać w wynikach konsoli.

getchar(); to tylko niewielka dodatkowa sztuczka, aby utrzymać konsolę w tyle podczas sprawdzania wyjścia.

Dane wejściowe: "First Line\nSecond Line\nThird Line\n"

Tworzy wynik:

First Line
Second Line
Third Line

2

Pyton


Możemy iteracyjnie użyć find()metody łańcuchowej Pythona do podzielenia łańcucha przy każdej nowej instancji linii (zauważ, że łańcuch wejściowy jest zakodowany na stałe jako input_str, ale może zostać zastąpiony przez raw_input ()):

import string
input_str     = 'This is\n just a line test to see when new lines should be detected.line'
output_pieces = []

while len(input_str) > 0:
    linepos = string.find(input_str, 'line')
    if linepos < 0:
        output_pieces.append(input_str)
        break
    else:
        if linepos > 0:
            output_pieces.append(input_str[0:linepos])
        input_str = input_str[(linepos+4):]

for piece in output_pieces:
    print piece

Po uruchomieniu powyższego skryptu uzyskujemy oczekiwany wynik (zwróć uwagę, że początkowe i końcowe białe znaki są zgodne z podziałem łańcucha przy każdym wystąpieniu nowej linii):

This is
 just a 
 test to see when new 
s should be detected.

2

PHP / GD

Dzielenie strun to bardzo skomplikowana sprawa. Chociaż kontynuowaliśmy i wprowadziliśmy dość podstawową implementację tego tak ważnego zadania domowego.

Działa bez żadnych zależności od najnowszej wersji PHP: Ilość przykładów ograniczona w opublikowanym kodzie, ponieważ mamy tutaj limit znaków około 40 000 znaków, który nie pasuje do przyzwoitej liczby łańcuchów demonstracyjnych.

Przykładowa wersja:

http://codepad.viper-7.com/YnGvCn

Dokładnie potwierdza twoje specyfikacje.

<?PHP

/**
 * My homework assignment is take a string and split it into pieces at every new line. I have no idea what to do! Please help!
 * Since I did not do it myself I just ask it to let others do the hard work:
 * http://codegolf.stackexchange.com/questions/16479/how-do-i-split-a-string
 * 
 * Nice
 */

//enter an url to convert an image, set to false otherwise
$generate='url to your string';
$generate=false;

//->My homework assignment is
$boring=true;

//a simple convertor for jpegs:

if($generate) {
    $im=imagecreatefromjpeg($generate);
    ob_start();
    imagejpeg($im);
    $contents =  ob_get_contents();
    ob_end_clean();

    echo base64_encode($contents);
    exit;
}



//->take a string

//man, just one string, we can handle many strings!

$complex=<<<'EOT'
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
EOT;


//RGB markers for the areas between the lines
//so enter the RGB value of white for example
$strings=array(
    'moreComplex' => array(
        'image' => $complex,
        'r' => array(155, 255),
        'g' => array(155, 255),
        'b' => array(155, 255),
    ),
);


foreach($strings AS $stringStyle => $string) {
    echo '<a href="?string='.$stringStyle.'">'.ucfirst($stringStyle).'</a><p>';
}

//check for a selection 
if(empty($_GET['string']) OR !isset($strings[$_GET['string']])) {
    exit;
}

$activeString=$strings[$_GET['string']];

$stringSourceBase64 = $activeString['image'];

//that's better

$stringSource=base64_decode($stringSourceBase64);

$sizes=getimagesizefromstring($stringSource);

$width=$sizes[0];
$height=$sizes[1];

$measuringX=round($width*.5);

//load the image
$im = imagecreatefromstring($stringSource);

//starting point of detection
$detectedStartY=false;
$linesFound=array();

$lastEndedY=false;

//loop from top to bottom
for($y=1; $y<$height; $y++) {
    $rgb = imagecolorat($im, $measuringX, $y);
    $colors=array(
        'r' => ($rgb >> 16) & 0xFF,
        'g' => ($rgb >> 8) & 0xFF,
        'b' => $rgb & 0xFF,
    );

    foreach($colors AS $colorName => $colorValue) {


        //->and split it into pieces at every new line.
        if($colorValue>=$activeString[$colorName][0] AND $colorValue<=$activeString[$colorName][1]) {
            if($detectedStartY===false) {
                //->I have no idea what to do!
                //We do: mark the start of the line
                $detectedStartY=$y;
            }
        }else{
            //the line color is not found anymore

            //see if we already detected a line
            if($detectedStartY!==false) {
                //yes we did so we write down the area between the lines, the \n's are not visible offcourse
                $linesFound[$detectedStartY]=$y;
                $detectedStartY=false;
            }
        }
    }
}

//->Please help!
//sure, see the beautiful results:

//because we all love tables
echo '<table width="100%">';

    echo '<tr><td valign="top">'; //and we love inline styling, just so fast

        echo '<img src="data:image/png;base64, '.$stringSourceBase64.'" border=1 />';

    echo '</td><td valign="top">';

        //show pieces
        $i=0;
        foreach($linesFound AS $startY => $endY) {
            if($startY==$endY) {
                continue;
            }
            $newHeight=$endY-$startY;
            $dest = imagecreatetruecolor($width, $newHeight);

            // Copy
            imagecopy($dest, $im, 0, 0, 0, $startY, $width, $newHeight);

            // Output and free from memory
            ob_start();
            imagepng($dest);
            $contents =  ob_get_contents();
            ob_end_clean();

            echo '
                Part #'.$i.' of string <small>(y= '.$startY.' - '.$endY.'px)</small><br>
                <img src="data:image/png;base64, '.base64_encode($contents).'" border=1 />
                <p>
            ';

            imagedestroy($dest);

            $i++;
        }

        imagedestroy($im);

    echo '</td></tr>';
echo '</table>';

//images courtesty of:
//http://indulgy.net/cC/V8/MF/0002501105.jpg
//http://2.bp.blogspot.com/_JGIxXn5d7dc/TBbM2Zu8qRI/AAAAAAAAABE/8WlYvhPusO8/s320/thong4.jpg
//http://cdn.iofferphoto.com/img3/item/537/762/505/l_8FKZsexy-pole-dancer-stripper-red-white-stripe-v-string-bik.jpg
//
//http://stackoverflow.com/questions/2329364/how-to-embed-images-in-a-single-html-php-file

2
from random import randint

def splitstring(s):
    while len(s):
        n=randint(2,20)
        yield s[:n]
        s=s[n:]

astring="This is a string. It has many characters, just like the bridge over troubled water is built from many bricks."

for i in splitstring(astring):
    print i

Nie chcę być wredny, więc oto działający kod Pythona, który dzieli twój łańcuch na części. Ponieważ jednak nie określiłeś, gdzie chcesz go podzielić, wybiorę tylko losowe lokalizacje. Mam nadzieję, że to w porządku.


Zabawne, ale określiłem, gdzie chcę podzielić ciąg.
Turion,

Pierwotnie przeczytałem pytanie jako „podziel ciąg według niektórych kryteriów i wydrukuj każdą część w nowym wierszu”.
nitro2k01

2

Pyton

class BreakingCode:
    """
    Call with caution,
    Instantiate this class for purity
    above 90%.
    """
    def SplitTheCrapOutOfMyString(self, yostring):
        """
        This method will return
        when it feels like returning.
        """
        print "Hey, how'you doin?"    # Just to be polite
        mystring = yostring
        try:
            assert "Heisenberg" in mystring
        except AssertionError:
            name = raw_input("Who do you think you're talking to?\n>>>")
            if name.startswith("H"):
                print "Yo, Mr.White"
        else:
            print "I'm the one who knocks"
        for eachword in mystring.split():
            print "{:_^40}".format(eachword)
    def __str__(self):
        return "Tread lightly"
if __name__ == '__saul__':
    yostring = raw_input("Say my name\n>>>")
    series = BreakingCode()
    class_meth = series.SplitTheCrapOutOfMyString(yostring)
    input()

2

W przypadku języków, które obsługują wyrażenie regularne i mają splitłatwo dostępne funkcje, należy zawsze używać go do dzielenia łańcucha. Pomaga to uniknąć ponownego wymyślania koła i zapewniać krótki i słodki kod. Użycie wyrażenia regularnego pozwala również przenieść kod na inny język bez zmiany wyrażenia regularnego.

Złe rozwiązanie

Jest to oczywiste rozwiązanie, w którym podziale \nlub \r\n:

Jawa

String result = input.split("\n|\r\n");

PHP

$result = preg_split('/\n|\r\n/', $input);

To rozwiązanie jest śmieciem i nigdy nie powinno być używane. W dzisiejszych czasach nie ma sensu unikać Unicode, raczej każdy programista powinien go zaakceptować i upewnić się, że twoja aplikacja jest gotowa na Unicode. Jeśli rozważasz tylko \nlub \r\njako nowy separator linii, piszesz oprogramowanie w latach 90. W tej erze Unicode należy uznać U + 0085, U + 2028, U + 2029 jako prawidłowy separator linii. Ponieważ Unicode jest aktualizowany co jakiś czas i zwykle zajmuje trochę czasu, zanim zdasz sobie sprawę, że został zaktualizowany, do Unicode może zostać dodany nowy separator linii. Nie martw się, ponieważ wszystkie silniki wyrażeń regularnych są gotowe na Unicode i są regularnie aktualizowane, aby były zgodne z najnowszym standardem Unicode. Więc jeśli używasz tłumaczonego języka, Twój kod będzie aktualny bez robienia czegokolwiek.

Zalecane rozwiązanie

Aby podzielić ciąg znaków przez terminator linii i być na bieżąco z ewolucją Unicode, podaj wyrażenie regularne ^i określ MULTILINEtryb.

Domyślnie ^dopasowuje tylko początek łańcucha. W MULTILINEtrybie dopasowuje ^ również początek linii, tj. Po zakończeniu linii.

Na przykład:

Jawa

String result = input.split("(?m)^");

PHP

$result = preg_split('/^/m', $input);

Zauważ, że z przodu znajduje się dodatkowy pusty ciąg znaków, wystarczy go usunąć lub zapętlić z indeksu 1.


Wyjaśnienie

Na pierwszy rzut oka wygląda to na dobrą odpowiedź z (nieco) działającym rozwiązaniem, w połączeniu z wyjaśnieniem z pewnymi zaleceniami kodowania najlepszych praktyk. Jednak samo rozwiązanie to troll ( „Wiem, użyję wyrażeń regularnych.” Teraz mają dwa problemy. ), A cały post jest posypany subtelnie błędnymi informacjami, które zatruwają każdego początkującego programistę.

  • Różne silniki wyrażeń regularnych obsługują różne zestawy funkcji. Jeśli silnik docelowy nie ma funkcji używanej w wyrażeniu regularnym, przeniesienie kodu nie jest tak proste, jak kopiowanie i wklejanie. Symulacja za pomocą obsługiwanych funkcji może być możliwa lub w ogóle nie można tego zrobić za pomocą samego wyrażenia regularnego.
  • Istnieją 2 typy silników : silnik tekstowy (oparty na automacie) i silnik sterowany wyrażeniem regularnym (cofanie). Pierwszy zwraca najdłuższy lewy ciąg, drugi zwraca skrajnie lewy ciąg (tendencyjny w kierunku kolejności eksploracji określonej przez regex). Ten sam regex może dawać różne wyniki dla 2 typów silników.
  • Nawet w przypadku tej samej funkcji inny silnik wyrażeń regularnych może mieć inną składnię, aby go określić.
  • Nawet w przypadku tej samej funkcji i tej samej składni różne silniki wyrażeń regularnych mogą mieć pewne różnice w działaniu podczas analizowania i dopasowywania. Pomijając błędy, różnica może wynikać z projektu silnika regex (może, ale nie musi, to udokumentowane).
  • W MULTILINEtrybie zachowanie ^i $zależy od definicji „terminatora linii”. Java uważa \r\n, \n, \r, \u0085, \u2028, \u2029aby być linia terminatora, gdzie \r\nsekwencja jest uważany atomowej. JavaScript uważa \n, \r, \u2028, \u2029być terminatory linii. Ruby uważa tylko \nza terminator linii.
  • splitfunkcja może mieć różną semantykę w różnych językach dla przypadków narożnych. Python nie dzieli się na puste dopasowania, Java usuwa końcowe ciągi znaków (chyba że określisz limit ujemny), JavaScript nie dzieli się na dopasowanie pustych ciągów o indeksie 0.
  • „Złe rozwiązanie” jest w rzeczywistości bardziej przenośne niż „zalecane rozwiązanie”. Jednak to, co należy uznać za terminator linii, zależy od specyfikacji tego, nad czym pracujesz (np. Kod źródłowy C).
  • Obecnie większość silników regex nie jest nawet zgodna z obsługą Unicode poziomu 1 . Mogą mieć właściwości i bloki Unicode, ale implementacja dla sekcji granicy linii jest wszędzie, jak wyjaśniono powyżej. JavaScript nie obsługuje nawet właściwości znaków Unicode!

1

Skrypt Bash

new_string=`echo $string`

To dzieli ciąg według nowego wiersza. Jeśli powtórzysz echo $new_string, zauważysz, że zastąpił on nową linię separatorami tablic.

Przykładowe dane wyjściowe:

[glitchmr@guava ~]$ string=$'some\nnice\nstring'
[glitchmr@guava ~]$ echo "$string"
some
nice
string
[glitchmr@guava ~]$ new_string=`echo $string`
[glitchmr@guava ~]$ echo "$new_string"
some nice string
[glitchmr@guava ~]$

1

Jawa

To nie czyta z pliku. Używane są wyrażenia regularne. Kod zakłada, że ​​odczytany ciąg ma znak „\ n” wskazujący nowy wiersz. Liczby 1,2,3,4 służą do oznaczenia podziału.

public static void main(String args[])
{

    String strSource = "1.This is a string.This is a string.This is a string.This is a string.This is a string.\n2.This is a string.This is a string.This is a string.This is a string.This is a string.\n3.This is a string.This is a string.This is a string.This is a string.This is a string.\n4.This is a string.This is a string.This is a string.This is a string.This is a string.";
    String[] tokens = Pattern.compile("\n").split(strSource,10) ;
    for (int loop=0;loop<tokens.length;loop++)
        System.out.println(tokens[loop]);
}

1

DO#

static class Module1{
    public static void Main()
{
        dynamic i = 0;
        foreach (object line_loopVariable in split_into_lines(Console.In.ReadToEnd())) {
            line = line_loopVariable;
            i += 1;
            Console.WriteLine("Line {0}: {1}", i, line);
        }
    }
    public static IEnumerable<string> split_into_lines(string text){
        dynamic temp_file_name = System.IO.Path.GetTempFileName();
        System.IO.File.WriteAllText(temp_file_name, text);
        return System.IO.File.ReadLines(temp_file_name);
    }
}

1

Nie określasz, czy „nowa linia”, na którą chcesz podzielić ciąg, rozróżnia małe i duże litery. Zakładam, że nieczuły.

public class SplitStringAtNewline
{
  public static final String STRING_TO_SPLIT = "Hellonew lineWorld";
  public static void main (String [] args)
  {
     System.out.println (
        String.join("",
          Pattern.compile("[nN][eE][wW] [lL][iI][nN][eE]")
              .splitAsStream(STRING_TO_SPLIT)
              .map((s) -> s + "\n")
              .collect(() -> new ArrayList<>(),
                    (c, e) -> c.add(e), (c1, c2) -> c1.addAll(c2))));

  }
}

1

Stary, w Powershell jest to bardzo łatwe.

Po prostu weź swój ciąg w następujący sposób:

$string = "Helloworld!"

Następnie zapętlaj losowy ascii, aż łańcuch zostanie podzielony na dwa w następujący sposób:

Do {
        1..($string.length+1) | % {$new_string+=[char](random (33..127))}
        rv new_string
} Until ($new_string -eq ($string.insert(($string.length/2)-1," ")))

ostatecznie powinieneś otrzymać podzielony ciąg, który możesz wypisać w następujący sposób:

Write-Host $new_string

Wydajność:

Witaj świecie!


1

Php

<? Spliter($yourstring); ?>

Oto jak dzielisz strunę. Czy to nie takie proste?

Wszystko, co musisz teraz zrobić, to napisać funkcję Spliter()


1

specyficzne dla bash

Świetna robota na !

Tak, podział łańcucha można wykonać w naprawdę prosty sposób:

string=$'foo\nbar\nbaz'

Najpierw musisz zainicjować zmienną, której będziesz używać do przechowywania podzielonego wyniku:

declare -a lines

Teraz, ponieważ każda linia jest oddzielona dwoma separatorami, początkiem lub końcem ciągu, będziesz potrzebować zmiennej do przechowywania pierwszego

limitA=0

Ok, teraz możesz wyszukać separator i zapisać swoje linie za pomocą pętli . Ponieważ nie mógł działać z wartością binarną, możesz użyć narzędzia takiego jak odpraca z wartościami szesnastkowymi, na przykład:

while read hexline
do
    addr=${hexline%% *}
    hexline="${hexline#$addr}"
    addr=$((16#$addr))
    for field in $hexline
    do
        if [ "$field" = "0a" ]
        then
            lines+=( "${string:limitA:addr-limitA}" )
            limitA=$(( addr + 1 ))
        fi
        ((addr++))
    done
done < <(od -A x -t x1 <<<"$string")

Teraz mamy podzielony ciąg przechowywany w zmiennej lines:

set | grep ^lines=
lines=([0]="foo" [1]="bar" [2]="baz")

Że możemy wydrukować za pomocą:

for (( idx=0 ; idx < ${#lines[@]} ; idx++ ))
do
    echo ${lines[idx]}
done

Umieszczenie tego wszystkiego w jednym skrypcie:

#!/bin/bash

string=$'this is a very long string containing spaces\nshorted, but containing comas...\nthird line.'
declare -a lines
limitA=0
while read hexline
do
    addr=${hexline%% *}
    hexline="${hexline#$addr}"
    addr=$((16#$addr))
    for field in $hexline
    do
        if [ "$field" = "0a" ]
        then
            lines+=( "${string:limitA:addr-limitA}" )
            limitA=$(( addr + 1 ))
        fi
        ((addr++))
    done
done < <(od -A x -t x1 <<<"$string")

for (( idx=0 ; idx < ${#lines[@]} ; idx++ ))
do
    echo $idx: ${lines[idx]}
done

Spowoduje to wydrukowanie:

0: this is a very long string containing spaces
1: shorted, but containing comas...
2: third line.

Nowoczesne bash

Ale stosując nowoczesną implementację bash , możesz przechowywać znaki kontrolne, takie jak nowa linia, w zmiennej, a nawet je testować:

#!/bin/bash

string=$'foo\nbar\nbaz'
declare -a lines
limitA=0
for (( idx=0 ; idx < ${#string} ; idx++ ))
do

    if [ "${string:idx:1}" = $'\n' ]
    then

        lines+=( "${string:limitA:idx-limitA}" )
        limitA=$(( idx + 1 ))
    fi
done
lines+=( "${string:limitA}" )

for (( idx=0 ; idx < ${#lines[@]} ; idx++ ))
do
    echo ${lines[idx]}
done

bash golf

Ale jeśli nie zależy Ci na czytelności, możesz napisać skondensowany skrypt w następujący sposób:

IFS=$'\n' read -d'' -a lines <<<$'foo\nbar\nbaz'

Skrypt w golfa może wyglądać następująco:

#!/bin/bash

IFS=$'\n' read -d'' -a lines <<<$'foo\nbar\nbaz'
printf "%s\n" ${lines[@]}

i da ten sam efekt: Łańcuch podziału pierwszego wiersza i zapisz go w tablicy o nazwie wiersze . Drugi wiersz wypisze każdy element „ linii ” macierzy , a po nim nowy wiersz .

konsola bash + vt

Ale ponieważ wiele osób korzysta z konsoli tekstowej opartej na standardzie ANSI VT , możesz użyć zachowań VT konsoli i napisać to jeszcze raz:

#!/bin/bash

echo $'foo\nbar\nbaz'

da taki sam wynik.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.