mboost-dp1
Hvem har lært nok Java 8 til at kunne skrive ulæselig kode?
- Forside
- ⟨
- Forum
- ⟨
- Tagwall
Fra tråd på LinkedIn.
Problem:
String s = "Sunset glow on the horizon";
lav en ny string med de bogstaver fra s som kun findes 1 gang i strengen.
Svaret er "uglwriz".
I tråden var der noget nydeligt kode med 2 for løkker som enhver nogenlunde udvikler der har set et curly bracket sprog før kunne læse og forstå.
Men ved brug af Java 8 features må det kunne laves som en enkelt statement.
String s2 = ?;
Nogle gode bud?
Jeg har en ikke køn løsning.
Problem:
String s = "Sunset glow on the horizon";
lav en ny string med de bogstaver fra s som kun findes 1 gang i strengen.
Svaret er "uglwriz".
I tråden var der noget nydeligt kode med 2 for løkker som enhver nogenlunde udvikler der har set et curly bracket sprog før kunne læse og forstå.
Men ved brug af Java 8 features må det kunne laves som en enkelt statement.
String s2 = ?;
Nogle gode bud?
Jeg har en ikke køn løsning.
Python:
Her er en oneliner, der lider lidt under af two .lower() kald:
Men ovenstående er O(n2), her er en der er O(n):
Her er en oneliner, der lider lidt under af two .lower() kald:
s = "Sunset glow on the horizon"
s2 = "".join([c for c in s.lower() if s.lower().count(c) == 1])
print(s2)
Men ovenstående er O(n2), her er en der er O(n):
from collections import OrderedDict
s = "Sunset glow on the horizon"
d = OrderedDict()
for c in s.lower():
. d[c] = d.get(c, 0) + 1
s2 = "".join([k for k, v in d.items() if v == 1])
print(s2)
C
Forbavsende bøvlet...
Forbavsende bøvlet...
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
const char *s = "Sunset glow on the horizon";
int frqs[26] = {0}; // 'z' - 'a' + 1 = 26
int len = strlen(s);
for (int i = 0; i < len; i++) {
char c = tolower(s[i]);
if (c >= 'a' && c <= 'z') {
frqs[c - 'a'] += 1;
}
}
for (int i = 0; i < len; i++) {
char c = tolower(s[i]);
if (c >= 'a' && c <= 'z' && frqs[c - 'a'] == 1) {
printf("%c", c);
frqs[c - 'a'] = 0;
}
}
printf("\n");
return 0;
}
Swift:
Hvis jeg skulle gætte, vil jeg tænke at man kan gøre det samme i Java 8 med Stream.reduce?
let s = "Sunset glow on the horizon"
let s2 = String(s.lowercased().reduce(into: [Character: Int](), { $0[$1] = ($0[$1] ?? 0) + 1 }).filter { $0.value == 1 }.map { $0.key })
Hvis jeg skulle gætte, vil jeg tænke at man kan gøre det samme i Java 8 med Stream.reduce?
Java 8
String s = "Sunset glow on the horizon";
String s2 = s.chars()
.mapToObj(c -> Character.toLowerCase((char)c))
.collect(Collectors.groupingBy(c -> c, LinkedHashMap::new, Collectors.counting()))
.entrySet()
.stream()
.filter(e -> e.getValue() == 1)
.map(e -> "" + e.getKey())
.collect(Collectors.joining());
System.out.println(s2); // uglwriz
#7
Det er meget tæt på min kode.
Jeg endte med:
Det er meget tæt på min kode.
Jeg endte med:
String s = "Sunset glow on the horizon";
String s2 = s.replace(" ", "").toLowerCase().chars()
.boxed().collect(Collectors.groupingBy(c -> c, LinkedHashMap::new, Collectors.counting()))
.entrySet().stream().filter(e -> e.getValue() == 1)
.map(e -> Character.toString((int)e.getKey())).collect(Collectors.joining());
System.out.println(s2);
#4
Er du ikke lidt nærig med byte'ne?
:-)
Den kode spilder 230 bytes. Men ...
Er du ikke lidt nærig med byte'ne?
:-)
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
int main()
{
const char *s = "Sunset glow on the horizon";
int frqs[1 << CHAR_BIT] = { 0 };
int len = strlen(s);
for (int i = 0; i < len; i++) {
char c = tolower(s[i]);
if (c >= 'a' && c <= 'z') {
frqs[c] += 1;
}
}
for (int i = 0; i < len; i++) {
char c = tolower(s[i]);
if (c >= 'a' && c <= 'z' && frqs[c] == 1) {
printf("%c", c);
frqs[c] = 0;
}
}
printf("\n");
return 0;
}
Den kode spilder 230 bytes. Men ...
arne_v (10) skrev:Den kode spilder 230 bytes. Men ...
Den spilder 230 * sizeof(int) på en 8-bit char platform :) Ja, man kunne supportere extended code page på den måde, men det er jo ikke unicode og derfor lidt meningsløst...
Det er jo et typisk alderdomstegn for C. Mangel på (nem) unicode support. Alle de andre løsninger listet her æder unicode til morgenmad, tænker jeg.
Men, mon ikke C koden er den hurtigste af løsningerne indtil videre ;)
larsp (12) skrev:arne_v (10) skrev:Den kode spilder 230 bytes. Men ...
Den spilder 230 * sizeof(int) på en 8-bit char platform :)
Ups. 230 int's.
larsp (12) skrev:
Ja, man kunne supportere extended code page på den måde, men det er jo ikke unicode og derfor lidt meningsløst...
Man undgår -'a' konstruktionen og man kan understøtte ikke fortløbende bogstaver.
Ikke fortløbende bogstaver i 8 bit vil være ISO-8859-whatever.
Algoritmen er ikke UTF-8 venlig.
Man kunne ret nemt lave den samme algoritme med wchar_t og dermed få unicode support.
larsp (12) skrev:
Det er jo et typisk alderdomstegn for C. Mangel på (nem) unicode support. Alle de andre løsninger listet her æder unicode til morgenmad, tænker jeg.
Java char er 16 bit. Så ja.
larsp (12) skrev:
Men, mon ikke C koden er den hurtigste af løsningerne indtil videre ;)
Sikkert.
arne_v (15) skrev:
Man kunne ret nemt lave den samme algoritme med wchar_t og dermed få unicode support.
#include <stdio.h>
#include <string.h>
#include <wctype.h>
#include <limits.h>
int main()
{
const wchar_t *s = L"Sunset glow on the horizon";
int frqs[sizeof(wchar_t) * (1 << CHAR_BIT)] = { 0 };
int len = wcslen(s);
for (int i = 0; i < len; i++) {
wchar_t c = towlower(s[i]);
if (iswalpha(c)) {
frqs[c] += 1;
}
}
for (int i = 0; i < len; i++) {
wchar_t c = towlower(s[i]);
if (iswalpha(c) && frqs[c] == 1) {
printf("%c", c);
frqs[c] = 0;
}
}
printf("\n");
return 0;
}
Unicode BMP support! :-)
#17 Interessant. Jeg prøvede koden og måtte tilføje og rette:
for at få det til at virke med nogle æøåer.
Algoritmen falder iøvrigt ... fuldstændigt ... fra hinanden hvis man fikser denne linje:
wchar_t er 4 bytes bred hos mig, så vi snupper lige 2^32 fra stakken ...
#include <locale.h>
#include <stddef.h>
#include <wchar.h>
setlocale(LC_ALL, "");
printf("%lc", c);
for at få det til at virke med nogle æøåer.
Algoritmen falder iøvrigt ... fuldstændigt ... fra hinanden hvis man fikser denne linje:
int frqs[1 << (sizeof(wchar_t) * CHAR_BIT)] = { 0 };
wchar_t er 4 bytes bred hos mig, så vi snupper lige 2^32 fra stakken ...
larsp (18) skrev:
setlocale(LC_ALL, "");
Default locale er C og den kan ikke så meget.
larsp (18) skrev:
Algoritmen falder iøvrigt ... fuldstændigt ... fra hinanden hvis man fikser denne linje:int frqs[1 << (sizeof(wchar_t) * CHAR_BIT)] = { 0 };
wchar_t er 4 bytes bred hos mig, så vi snupper lige 2^32 fra stakken ...
Ups.
Jeg antog at wchar_t var 16 bit.
Hvilket var en uheldig antagelse, da C naturligvis ikke garanterer dette.
Hvilken compiler/platform bruger 32 bit wchar_t?
larsp (20) skrev:
Det er en Ubuntu 22.04.3 med kernel: 5.15.0-79-generic x86_64, gcc: 11.4.0
Jeg testede lige lidt.
Det ser faktisk ud som om wchar_t er 4 på alle platforme undtagen Windows (både mit Linux sytsem og mit VMS system har 4).
Det shift var ikke en god ide.
GCC har -fshort-wchar som vil ændre til 2 på ikke-Windows platforme. Men ingen wcs funktioner virker med det, så det er at skyde sig selv i foden.
#22
Jo men ...
C standarden siger at:
så C garanterer at et valid tegn i en locale kan opbaveres i wchar_t.
Men C udspecificerer ikke hvilke tegn/locale der skal understøttes.
Så wchar_t kan være næsten hvad som helst.
Ofte er dfet ligegyldigt hvad det er, men i det her tilfælde ville jeg gerne have antal mulige værdier.
Så jeg forsøgte med:
antal char i en wchar_t * (1 << amtal bits i en char)
og fejlede fordi der er ikke nogen upper limit på størrelse og mange platforme har bare valgt 4.
Næste forsøg er WCHAR_MAX. Hvis de var bare en lille smule brugervenlige ville den indeholde den højeste brugbare værdi og ikke højeste værdi der kan gemmes i den type integer som wchar_t er.
No luck. 2147483647.
Jo men ...
C standarden siger at:
wchar_t
which is an integer type whose range of values can represent distinct codes for all
members of the largest extended character set specified among the supported locales; the null character shall have the code value zero
så C garanterer at et valid tegn i en locale kan opbaveres i wchar_t.
Men C udspecificerer ikke hvilke tegn/locale der skal understøttes.
Så wchar_t kan være næsten hvad som helst.
Ofte er dfet ligegyldigt hvad det er, men i det her tilfælde ville jeg gerne have antal mulige værdier.
Så jeg forsøgte med:
antal char i en wchar_t * (1 << amtal bits i en char)
og fejlede fordi der er ikke nogen upper limit på størrelse og mange platforme har bare valgt 4.
Næste forsøg er WCHAR_MAX. Hvis de var bare en lille smule brugervenlige ville den indeholde den højeste brugbare værdi og ikke højeste værdi der kan gemmes i den type integer som wchar_t er.
No luck. 2147483647.
Ang. opgaven i #1 er pythons OrderedDict vel den noget nær perfekte datastruktur og med få linjer kode kan man således løse opgaven med glimrende performance i python. For at kunne følge med i C, i unicode, vil man være nød til at skrive et ret omstændeligt program, med risiko for alle mulige fejl, hvorefter C programmet nok vil tage føringen i performance. Det er jo et ret sigende eksempel på sprogenes styrker og svagheder.
De andre onelinere herover er totalt ulæselige for mig, haha ... "{ $0[$1] = ($0[$1] ?? 0) + 1 }" what??
Kan vi mon få en løsning i Rust :)
De andre onelinere herover er totalt ulæselige for mig, haha ... "{ $0[$1] = ($0[$1] ?? 0) + 1 }" what??
Kan vi mon få en løsning i Rust :)
larsp (24) skrev:For at kunne følge med i C, i unicode, vil man være nød til at skrive et ret omstændeligt program, med risiko for alle mulige fejl,
Problemet er som altid at C ikke definerer tingene præcist men lader meget være op til implementationen.
C99 har:
const wchar_t *s = L"Sunset glow on the horizon";
og streng funktioner wcslen, towlower og iswalpha.
Men standarden garanterer kun at wchar_t kan indeholde alle tegn som den pågældende implementation understøtter.
Hvis makro __STDC_ISO_10646__ er defineret skal værdierne være Unicode.
Praksis synes at være at wchar_t på Windows er UTF-16 og på ikke-Windows er UTF-32.
Der er ikke nogen god måde at få antal mulige værdier. På Windows kunne man forsigtigt antage 65536 og på ikke-Windows kunne man antage enten totale antal unicode værdier 149186 eller hvis man antager BMP 65536.
C11 har tilføjet:
const char16_t *s = u"Sunset glow on the horizon";
const char32_t *s = U"Sunset glow on the horizon";
men ingen funktioner.
Hvis henholdsvis __STDC_UTF_16__ og __STDC_UTF_32__ er defineret skal de indeholde UTF-16 og UTF-32.
Og i praksis gør de.
C23 kræver at de er UTF-16 og UTF-32.
#C
Jeg tror iøvrigt at algoritmen med frqs har yderligere en komplikation.
Hvis char eller wchar_t default er signed vil man få negative værdier for nogle tegn.
Så længe man bruger a..z test og et superset af ASCII er det OK. Men med support for nationale tegn eller et tegnsæt som ikke er et superset af ASCII (EBCDIC) har man et potentielt problem.
32 bit wchar_t er dog sikker - 149186 er ikke stort nok til at gå i negativ.
Jeg tror iøvrigt at algoritmen med frqs har yderligere en komplikation.
Hvis char eller wchar_t default er signed vil man få negative værdier for nogle tegn.
Så længe man bruger a..z test og et superset af ASCII er det OK. Men med support for nationale tegn eller et tegnsæt som ikke er et superset af ASCII (EBCDIC) har man et potentielt problem.
32 bit wchar_t er dog sikker - 149186 er ikke stort nok til at gå i negativ.
larsp (24) skrev:De andre onelinere herover er totalt ulæselige for mig, haha ... "{ $0[$1] = ($0[$1] ?? 0) + 1 }" what??
$0 = første argument i en closure
$1 = næste argument i en closure
Kunne også være skrevet som
{ d[c] = (d[c] ?? 0) + 1 }
Og I Swift giver et key access på dictionary en optional tilbage, du ved, i tilfælde af værdien ikke findes. Så derfor skal vi lige bruge en default værdi (0)
Det er det samme du gør her med d.get(c, 0) i din oprindelige kode.
larsp (24) skrev:
Kan vi mon få en løsning i Rust :)
Jeg kan ikke klare en one linier.
Men noget simpel kode:
fn main() {
let s = "Sunset glow on the horizon";
let mut res = String::from("");
for c in s.to_lowercase().chars() {
if s.to_lowercase().matches(c).count() == 1 {
res.push(c)
}
}
println!("{}", res);
}
#27 Aha, giver mening. $0 og $1 minder om parametre i bash funktioner :P
#28 Meget ligefrem kode
Ang. OrderedDict i Python, det er åbenbart ophøjet til krav at man kan forvente {} at bevare insertion order fra Python 3.7 og frem. Jeg synes stadig det er på sin plads at bede om OrderedDict eksplicit hvis man har brug for den egenskab.
#28 Meget ligefrem kode
Ang. OrderedDict i Python, det er åbenbart ophøjet til krav at man kan forvente {} at bevare insertion order fra Python 3.7 og frem. Jeg synes stadig det er på sin plads at bede om OrderedDict eksplicit hvis man har brug for den egenskab.
larsp (29) skrev:
#28 Meget ligefrem kode
Kender man ikke et sprog specielt godt, så bliver kode ofte meget ligefrem.
larsp (29) skrev:
Ang. OrderedDict i Python, det er åbenbart ophøjet til krav at man kan forvente {} at bevare insertion order fra Python 3.7 og frem. Jeg synes stadig det er på sin plads at bede om OrderedDict eksplicit hvis man har brug for den egenskab.
Enten eksplicit valg af OrderedDict eller et test på Python version.
#3
Et vigtigt element i Python løsningerne er hvad jeg kalder "den vandrette for løkke". Konstruktionen har sikkert et rigtigt navn i Python.
Men det pussige er at det er en meget gammel konstruktion.
Fortran har den (under navnet "implied do loop").
eller mere gammeldags:
Et vigtigt element i Python løsningerne er hvad jeg kalder "den vandrette for løkke". Konstruktionen har sikkert et rigtigt navn i Python.
Men det pussige er at det er en meget gammel konstruktion.
Fortran har den (under navnet "implied do loop").
program horfor
integer*4 ia(5)
integer*4 i
data (ia(i),i=1,5,2)/3*123/
data (ia(i),i=2,4,2)/2*456/
write(*,'(1x,5I4)') (ia(i),i=1,5)
end
eller mere gammeldags:
dimension ia(5)
data (ia(i),i=1,5,2)/3*123/
data (ia(i),i=2,4,2)/2*456/
write(*,'(1x,5I4)') (ia(i),i=1,5)
end
arne_v (31) skrev:#3
Et vigtigt element i Python løsningerne er hvad jeg kalder "den vandrette for løkke". Konstruktionen har sikkert et rigtigt navn i Python.
De hedder "list comprehensions". Jeg har ikke nogen god idé til en dansk oversættelse. Der er også dictionary comprehensions:
d = {k:v for k, v in iterable}
Dine Fortraneksempler er ulæselige for mig. Hvor er løkke-featuren? i=1,5,2? Det er kun tre elementer, eller 1 til 5 step 2. Er det i=1,5 som looper fem gange svarende til ia(5)?
#32 #33 #34
Fortran implied do loop er klart mere primitiv og ikke så fleksibel som Python list comprehension.
Men respekt for alder.
Jeg lavede lidt research.
Implied do loop er vist på side 24 i http://bitsavers.informatik.uni-stuttgart.de/pdf/i... og det dokument er dateret 15. oktober 1956.
Python fik list comprehension i version 2.0 44 år senere.
Man bliver lidt klogere på 44 år. :-)
Fortran implied do loop er klart mere primitiv og ikke så fleksibel som Python list comprehension.
Men respekt for alder.
Jeg lavede lidt research.
Implied do loop er vist på side 24 i http://bitsavers.informatik.uni-stuttgart.de/pdf/i... og det dokument er dateret 15. oktober 1956.
Python fik list comprehension i version 2.0 44 år senere.
Man bliver lidt klogere på 44 år. :-)
#33
heh, 1-based arrays. Det minder mig om da min mor var i Stockholm den anden uge og på undergrundsbanen så hun at der hang en programmerings gåde (fra et konsulentfirma der hyrer folk) med noget array/string manipulation (for at lave en URL man kan besøge)
Hun var meget forvirret indtil jeg forklarede at array indexing er 0-based i Python (og de fleste andre sprog) :p
I PL/I starter arrays nemlig også med 1
heh, 1-based arrays. Det minder mig om da min mor var i Stockholm den anden uge og på undergrundsbanen så hun at der hang en programmerings gåde (fra et konsulentfirma der hyrer folk) med noget array/string manipulation (for at lave en URL man kan besøge)
Hun var meget forvirret indtil jeg forklarede at array indexing er 0-based i Python (og de fleste andre sprog) :p
I PL/I starter arrays nemlig også med 1
#37
Pascal:
Pascal:
program arix(input,output);
type
r4 = -2..7;
e5 = (a,b,c,d,e,f,g,h,i,j);
var
a1 : array [1..10] of integer;
a2 : array [0..9] of integer;
a3 : array [-5..4] of integer;
a4 : array [r4] of integer;
a5 : array [e5] of integer;
ix1, ix2, ix3 : integer;
ix4 : r4;
ix5 : e5;
begin
for ix1 := lower(a1) to upper(a1) do begin
a1[ix1] := ix1 * ix1;
writeln(ix1, ' ', a1[ix1]);
end;
for ix2 := lower(a2) to upper(a2) do begin
a2[ix2] := ix2 * ix2;
writeln(ix2, ' ', a2[ix2]);
end;
for ix3 := lower(a3) to upper(a3) do begin
a3[ix3] := ix3 * ix3;
writeln(ix3, ' ', a3[ix3]);
end;
for ix4 := lower(a4) to upper(a4) do begin
a4[ix4] := ix4 * ix4;
writeln(ix4, ' ', a4[ix4]);
end;
for ix5 := lower(a5) to upper(a5) do begin
a5[ix5] := ord(ix5) * ord(ix5);
writeln(ix5, ' ', a5[ix5]);
end;
end.
#38
Pascal har godt nok mange features hvad angår arrays og deres indexes. Det er pudsigt at de nuværende populære sprog har valgt at droppe den slags fuldstændig. Vil man have funky indexes må man gribe fat i et dictionary eller map.
e5 er vel en art enum?
"array [0..9] of integer" gør ondt i mine øjne, da jeg antager at 9 er inklusiv, så der er 10 elementer. Det er så normalt i de moderne sprog at slutangivelsen er eksklusiv, f.eks. Python:
Pascal har godt nok mange features hvad angår arrays og deres indexes. Det er pudsigt at de nuværende populære sprog har valgt at droppe den slags fuldstændig. Vil man have funky indexes må man gribe fat i et dictionary eller map.
e5 er vel en art enum?
"array [0..9] of integer" gør ondt i mine øjne, da jeg antager at 9 er inklusiv, så der er 10 elementer. Det er så normalt i de moderne sprog at slutangivelsen er eksklusiv, f.eks. Python:
>>> a = "123456789abcdefg"
>>> a[0:9]
'123456789'
#40
Matematikere elsker forvirrende konstruktioner (og græske bogstaver som variabler, i stedet for faktisk navne -- hvilket er hvorfor de er så dårlige til at programmere)
Jeg synes personligt dette her er nemmere at forstå (Swift ranges):
0...9
0..<9
https://developer.apple.com/documentation/swift/ra...
Matematikere elsker forvirrende konstruktioner (og græske bogstaver som variabler, i stedet for faktisk navne -- hvilket er hvorfor de er så dårlige til at programmere)
Jeg synes personligt dette her er nemmere at forstå (Swift ranges):
0...9
0..<9
https://developer.apple.com/documentation/swift/ra...
larsp (39) skrev:
Pascal har godt nok mange features hvad angår arrays og deres indexes. Det er pudsigt at de nuværende populære sprog har valgt at droppe den slags fuldstændig. Vil man have funky indexes må man gribe fat i et dictionary eller map.
Der er en historisk kontekst.
Wirth designede Pascal til brug for undervisning. De studerende skulle lære pæn programmering. Bruger bestemte array index kan undgå nogle "grimme" beregninger af array index.
Ritchie designed C for Unix. Det skulle ikke være pænt - det skulle være effektivt. Så altid 0 baseret index gav mening. Det sparer nogle maskin instruktioner. Og han havde også langt mindre plads at boltre sig på end Wirth.
Den første Pascal blev implementeret på en CDC Cyber 170 som har 18 bit addresser af 60 bit ord = 262144 ord @ 60 bit = 2621440 bytes @ 6 bit. Den første C og Unix blev implementeret på en DEC PDP-11 som har 16 bit adresser af 8 bit bytes = 65536 bytes @ 8 bit.
Da Stroustrup designede C++ var det et bevidst valg at det skulle være C kompatibelt. Så altid 0 baseret. De første C++ compilere (cfront) var ikke engang compilere men transpilere efter moderne terminologi da de oversatte C++ til C.
Da Gosling designede Java var det overordnede mål et sprog som var mere sikker og simplere end C++ (at Java er blevet kompleks med årene er en anden sag - det vidste han ikke dengang i midt 90erne). Hvis det skulle være simplere end C++ så var det ikke sagen med flere muligheder for array index. Så altid 0 baseret.
Da Hejlsberg designed C# var det overordnede mål et sprog som var en forbedret Java. Så altid 0 baseret. Også selvom han jo oprindeligt kommer fra Pascal verdenen.
Language designer anno 2023: det er da ikke muligt at have andet end 0 baserede array index??
larsp (39) skrev:
e5 er vel en art enum?
Ja. Pascal syntax for enum.
larsp (39) skrev:
Det er så normalt i de moderne sprog at slutangivelsen er eksklusiv, f.eks. Python:>>> a = "123456789abcdefg"
>>> a[0:9]
'123456789'
Der er jo 3 varianter af dette:
str.substr(startincl, endincl)
str.substr(startincl, endexcl)
str.substr(startincl, length)
Jeg kan faktisk bedst lide den tredie!
:-)
arne_v (43) skrev:
Der er jo 3 varianter af dette:
str.substr(startincl, endincl)
str.substr(startincl, endexcl)
str.substr(startincl, length)
The votes are in.
str.substr(startincl, endincl)
Fortran
program strix
character*5 s
s = 'ABCDE'
write(*,*) s(1:3)
write(*,*) s(2:4)
write(*,*) s(3:5)
end
str.substr(startincl, endexcl)
Python:
s = 'ABCDE'
print(s[0:3])
print(s[1:4])
print(s[2:5])
Java:
public class Strix {
public static void main(String[] args) {
String s = "ABCDE";
System.out.println(s.substring(0, 3));
System.out.println(s.substring(1, 4));
System.out.println(s.substring(2, 5));
}
}
str.substr(startincl, length)
Cobol:
IDENTIFICATION DIVISION.
PROGRAM-ID.STRIX.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 S PIC X(5) VALUE "ABCDE".
PROCEDURE DIVISION.
MAIN-PARAGRAPH.
DISPLAY S(1:3)
DISPLAY S(2:3)
DISPLAY S(3:3)
STOP RUN.
Pascal (Delphi/FPC):
program strix(input, output);
var
s : string;
begin
s := 'ABCDE';
writeln(copy(s, 1, 3));
writeln(copy(s, 2, 3));
writeln(copy(s, 3, 3));
end.
C++:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "ABCDE";
cout << s.substr(0, 3) << endl;
cout << s.substr(1, 3) << endl;
cout << s.substr(2, 3) << endl;
return 0;
}
C#:
using System;
public class Strix
{
public static void Main(string[] args)
{
string s = "ABCDE";
Console.WriteLine(s.Substring(0, 3));
Console.WriteLine(s.Substring(1, 3));
Console.WriteLine(s.Substring(2, 3));
}
}
arne_v (43) skrev:Der er jo 3 varianter af dette:
str.substr(startincl, endincl)
str.substr(startincl, endexcl)
str.substr(startincl, length)
Jeg kan faktisk bedst lide den tredie!
Python slices har nu nogle frække muligheder der er logiske i det der bruges anden variant. Blank betyder første eller sidste element, negativ betyder trukket fra enden:
>>> a = "ABCDE"
>>> a[:-1], a[-1:]
('ABCD', 'E')
Claus Jørgensen (41) skrev:Jeg synes personligt dette her er nemmere at forstå (Swift ranges):
0...9
0..<9
https://developer.apple.com/documentation/swift/ra...
Det er faktisk en helt pæn syntaks.
Har Swift tilsvarende shortcuts som Python, vist i #45?
larsp (45) skrev:arne_v (43) skrev:Der er jo 3 varianter af dette:
str.substr(startincl, endincl)
str.substr(startincl, endexcl)
str.substr(startincl, length)
Jeg kan faktisk bedst lide den tredie!
Python slices har nu nogle frække muligheder der er logiske i det der bruges anden variant. Blank betyder første eller sidste element, negativ betyder trukket fra enden:
>>> a = "ABCDE"
>>> a[:-1], a[-1:]
('ABCD', 'E')
At man kan undlade at angive længden og at det betyder resten kendes også fra andre sprog.
At bruge negativ for at tælle RtoL i.s.f. LtoR kan jeg ikke umiddelbart komme i tanke om andre sprog som gør.
Python kode er meget udtryksfuldt.
#41
Ja. Det er faktisk en fornuftig eksplicit syntaks.
Jeg kan ikke lide at de starter med et eksempel med floating point - givet at ikke alle text decimale udstryk kan repræsenteres eksakt i binær floating point er inkl. og ekskl. upper bound lidt uldent for floationg point.
(jeg antager at 0.0 og 5.0 er floating point konstanter og ikke decimal konstanter i Swift)
Ja. Det er faktisk en fornuftig eksplicit syntaks.
Jeg kan ikke lide at de starter med et eksempel med floating point - givet at ikke alle text decimale udstryk kan repræsenteres eksakt i binær floating point er inkl. og ekskl. upper bound lidt uldent for floationg point.
(jeg antager at 0.0 og 5.0 er floating point konstanter og ikke decimal konstanter i Swift)
Opret dig som bruger i dag
Det er gratis, og du binder dig ikke til noget.
Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.