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 trollujące kod . Proszę nie brać poważnie pytania i / lub odpowiedzi. Więcej informacji tutaj .
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 trollujące kod . Proszę nie brać poważnie pytania i / lub odpowiedzi. Więcej informacji tutaj .
Odpowiedzi:
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 \n
bez 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ć \n
w swojej książce.
(Uwaga: jeśli zastanawiasz się, o czym mówimy \n
bez 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”), putc
aby 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 ilestrlen()
służy do uzyskania rzeczywistej długości do działania.
...
Próbujemy przekonać czytelnika, że
strncmp
jest 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ż
\n
kody, powiedz tab ... który może być użyty do tajemniczego pominięcia znaków na wyjściu :-P)
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.
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ć.
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:
printf
funkcji dzielenia ciągów#define
(a nawet tych, którzy rozumieją ) Można to zrobić w kilku wierszach kodu za pomocą następującego prostego algorytmu:
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:
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.
IO
Monada 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
#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));
}
std::strstream
strstream
std::
prefiksuPython 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);
#define
? ;-)
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
split
eval
'
lub,
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)
To takie proste, każdy programista mógłby to zrobić.
Najpierw musimy zmienić hosts
plik, aby .com, .net, .org
mapować 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 :)
string.split('/n');
o zdezorientowaniu ucznia teoretycznego :).
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ż:
SplitStr
zawsze dzieli znakami nowej linii, bez względu argument jest, nie wiem, czy zamierzona
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ę:
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;
}
}
}
}
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.
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?
... jest tu całkiem spora lista trollingu.
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ł.
HAI
CAN HAZ STDIO?
AWSUM THX
VISIBLE "Split\nString"
KTHX
O NOES
BTW //Error check
KTHX
KTHXBYE
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 const
sł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
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.
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
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.
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()
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.
Jest to oczywiste rozwiązanie, w którym podziale \n
lub \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 \n
lub \r\n
jako 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.
Aby podzielić ciąg znaków przez terminator linii i być na bieżąco z ewolucją Unicode, podaj wyrażenie regularne ^
i określ MULTILINE
tryb.
Domyślnie ^
dopasowuje tylko początek łańcucha. W MULTILINE
trybie 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.
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ę.
MULTILINE
trybie zachowanie ^
i $
zależy od definicji „terminatora linii”. Java uważa \r\n
, \n
, \r
, \u0085
, \u2028
, \u2029
aby być linia terminatora, gdzie \r\n
sekwencja jest uważany atomowej. JavaScript uważa \n
, \r
, \u2028
, \u2029
być terminatory linii. Ruby uważa tylko \n
za terminator linii.split
funkcja 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.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 ~]$
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]);
}
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);
}
}
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))));
}
}
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!
Świetna robota na bash !
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ż bash nie mógł działać z wartością binarną, możesz użyć narzędzia takiego jak od
praca 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.
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
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 .
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.