Próbuję wykonać programowanie dynamiczne na podstawie liczby znaków w zdaniu. Która litera alfabetu angielskiego zajmuje najwięcej pikseli na ekranie?
Próbuję wykonać programowanie dynamiczne na podstawie liczby znaków w zdaniu. Która litera alfabetu angielskiego zajmuje najwięcej pikseli na ekranie?
Odpowiedzi:
Hmm, zobaczmy:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
cccccccccccccccccccccccccccccccccccccccc
ddddddddddddddddddddddddddddddddddddddd
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
ffffffffffffffffffffffffffffffffffffffff
gggggggggggggggggggggggggggggggggggggggg
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
llllllllllllllllllllllllllllllllllllllllll
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
oooooooooooooooooooooooooooooooooooooooo
pppppppppppppppppppppppppppppppppppppppp
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
ssssssssssssssssssssssssssssssssssssssss
tttttttttttttttttttttttttttttttttttttttt
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
Wygrywa
Oczywiście jest to głupi eksperyment empiryczny. Nie ma jednej odpowiedzi, na którą list jest najszerszy. To zależy od czcionki. Musisz więc przeprowadzić podobny eksperyment empiryczny, aby znaleźć odpowiedź dla swojego środowiska. Ale faktem jest, że większość czcionek jest zgodna z tymi samymi konwencjami, a wielkie W będzie najszersze.
Gist z tymi szerokościami znaków w postaci współczynnika (W = 100) uchwyconymi tutaj za pomocą tej konkretnej przykładowej czcionki:
https://gist.github.com/imaurer/d330e68e70180c985b380f25e195b90c
W nawiązaniu do niezwykle praktycznej odpowiedzi Neda Batcheldera, ponieważ przyszedłem tutaj, zastanawiając się nad cyframi:
0000000000000000000000000000000000000000
1111111111111111111111111111111111111111
2222222222222222222222222222222222222222
3333333333333333333333333333333333333333
4444444444444444444444444444444444444444
555555555555555555555555555555555555555555
666666666666666666666666666666666666666666
7777777777777777777777777777777777777777
8888888888888888888888888888888888888888
9999999999999999999999999999999999999999
font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
font-size: 15px;
Och, to Apple, zawsze stara się być trochę inny ...
font-variant-numeric
: liczb proporcjonalnych pozwalają na różne szerokości, zarówno w glifie, jak i odstępach, podczas gdy cyfry tabelaryczne muszą przestrzegać podobnych zasad jak czcionki o stałej szerokości.
Co powiesz na programowe rozwiązanie?
var capsIndex = 65;
var smallIndex = 97
var div = document.createElement('div');
div.style.float = 'left';
document.body.appendChild(div);
var highestWidth = 0;
var elem;
for(var i = capsIndex; i < capsIndex + 26; i++) {
div.innerText = String.fromCharCode(i);
var computedWidth = window.getComputedStyle(div, null).getPropertyValue("width");
if(highestWidth < parseFloat(computedWidth)) {
highestWidth = parseFloat(computedWidth);
elem = String.fromCharCode(i);
}
}
for(var i = smallIndex; i < smallIndex + 26; i++) {
div.innerText = String.fromCharCode(i);
var computedWidth = window.getComputedStyle(div, null).getPropertyValue("width");
if(highestWidth < parseFloat(computedWidth)) {
highestWidth = parseFloat(computedWidth);
elem = String.fromCharCode(i);
}
}
div.innerHTML = '<b>' + elem + '</b>' + ' won';
Wielka litera „M” jest zwykle najszersza.
W zależności od platformy może istnieć sposób „getWidth” z ciągu lub funkcji DrawText () z właściwością width.
Zrobiłbym prosty algortime, który wykorzystywałby potrzebną czcionkę, a następnie przejrzałem alfabet i zapisał go w małej konfiguracji lub po prostu obliczył przy inicjalizacji jako pętla od A do Z, nie jest tak trudny.
To zależy również od czcionki. Zrobiłem to 1 lub 2 lata temu z Processing i Helvetica i jest to ILJTYFVCPAXUZKHSEDORGNBQMW w kolejności rosnącej liczby pikseli. Chodzi o to, aby narysować tekst na płótnie czcionką, na którą patrzysz, policzyć piksele, a następnie posortować za pomocą HashMap lub Dictionary.
Oczywiście może to nie być bezpośrednio niekorzystne dla twojego zastosowania, ponieważ oblicza obszar pikseli, a nie tylko szerokość. Może to być trochę przesada.
void setup() {
size(30,30);
HashMap hm = new HashMap();
fill(255);
PFont font = loadFont("Helvetica-20.vlw");
textFont(font,20);
textAlign(CENTER);
for (int i=65; i<91; i++) {
background(0);
text(char(i),width/2,height-(textDescent()+textAscent())/2);
loadPixels();
int white=0;
for (int k=0; k<pixels.length; k++) {
white+=red(pixels[k]);
}
hm.put(char(i),white);
}
HashMap sorted = getSortedMap(hm);
String asciiString = new String();
for (Iterator<Map.Entry> i = sorted.entrySet().iterator(); i.hasNext();) {
Map.Entry me = (Map.Entry)i.next();
asciiString += me.getKey();
}
println(asciiString); //the string in ascending pixel order
}
public HashMap getSortedMap(HashMap hmap) {
HashMap map = new LinkedHashMap();
List mapKeys = new ArrayList(hmap.keySet());
List mapValues = new ArrayList(hmap.values());
TreeSet sortedSet = new TreeSet(mapValues);
Object[] sortedArray = sortedSet.toArray();
int size = sortedArray.length;
// a) Ascending sort
for (int i=0; i<size; i++) {
map.put(mapKeys.get(mapValues.indexOf(sortedArray[i])), sortedArray[i]);
}
return map;
}
Arial 30px w Chrome - wygrywa .
Rozwiązanie do obliczania szerokości czcionek trochę podobne do rozwiązania opublikowanego przez xxx zostało opublikowane przez Alexa Michaela na jego blogu (co zabawnie mnie tutaj linkowało).
Podsumowanie:
Oryginalny post: http://alexmic.net/letter-pixel-count/
Kod:
# -*- coding: utf-8 -*-
from __future__ import division
import os
from collections import defaultdict
from math import sqrt
from PIL import Image, ImageDraw, ImageFont
# Make a lowercase + uppercase alphabet.
alphabet = 'abcdefghijklmnopqrstuvwxyz'
alphabet += ''.join(map(str.upper, alphabet))
def draw_letter(letter, font, save=True):
img = Image.new('RGB', (100, 100), 'white')
draw = ImageDraw.Draw(img)
draw.text((0,0), letter, font=font, fill='#000000')
if save:
img.save("imgs/{}.png".format(letter), 'PNG')
return img
def count_black_pixels(img):
pixels = list(img.getdata())
return len(filter(lambda rgb: sum(rgb) == 0, pixels))
def available_fonts():
fontdir = '/Users/alex/Desktop/English'
for root, dirs, filenames in os.walk(fontdir):
for name in filenames:
path = os.path.join(root, name)
try:
yield ImageFont.truetype(path, 100)
except IOError:
pass
def letter_statistics(counts):
for letter, counts in sorted(counts.iteritems()):
n = len(counts)
mean = sum(counts) / n
sd = sqrt(sum((x - mean) ** 2 for x in counts) / n)
yield letter, mean, sd
def main():
counts = defaultdict(list)
for letter in alphabet:
for font in available_fonts():
img = draw_letter(letter, font, save=False)
count = count_black_pixels(img)
counts[letter].append(count)
for letter, mean, sd in letter_statistics(counts):
print u"{0}: {1:.2f} ± {2:.2f}".format(letter, mean, sd)
if __name__ == '__main__':
main()
Będzie to zależeć od czcionki. Stworzyłbym mały program w języku programowania, w którym czujesz się najlepiej, w którym rysujesz każdą literę alfabetu w bitmapie wielkości m. Zainicjuj każdy piksel kolorem białym. Następnie policz liczbę białych pikseli po narysowaniu każdej litery i zapisz tę liczbę. Najwyższy znaleziony numer to ten, którego szukasz.
EDYCJA: Jeśli w rzeczywistości interesuje Cię tylko, który z nich zajmuje największy prostokąt (ale wygląda na to, że naprawdę po nim jesteś, a nie piksele), możesz użyć różnych wywołań API, aby znaleźć rozmiar, ale to zależy od twój język programowania. Na przykład w Javie użyłbyś klasy FontMetrics.
Wiem, że przyjęta odpowiedź tutaj to W, W jest dla WIN.
Jednak w tym przypadku W jest również dla szerokości. W zastosowanym studium przypadku zastosowano prosty test szerokości w celu zbadania pikseli, ale była to tylko szerokość, a nie całkowita liczba pikseli. Jako prosty licznik przykład przyjęta odpowiedź zakłada, że O i Q zajmują tę samą liczbę pikseli, ale zajmują tylko tyle samo miejsca.
Zatem W zajmuje najwięcej miejsca . Ale czy to są wszystkie piksele, które są rozbite?
Zdobądźmy trochę danych empirycznych. Stworzyłem obrazy imgur z następujących B, M i W. Następnie przeanalizowałem ich liczbę pikseli (patrz poniżej), oto wyniki:
B: 114 pikseli
M: 150 pikseli
W: 157 pikseli
Oto w jaki sposób wprowadziłem je na płótno i przeanalizowałem surowe dane pikseli z obrazów.
var imgs = {
B : "//i.imgur.com/YOuEPOn.png",
M : "//i.imgur.com/Aev3ZKQ.png",
W : "//i.imgur.com/xSUwE7w.png"
};
window.onload = function(){
for(var key in imgs){(function(img,key){
var Out = document.querySelector("#"+key+"Out");
img.crossOrigin = "Anonymous";
img.src=imgs[key];
img.onload = function() {
var canvas = document.querySelector('#'+key);
(canvas.width = img.width,canvas.height = img.height);
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
var data = context.getImageData(0, 0, img.width, img.height).data;
Out.innerHTML = "Total Pixels: " + data.length/4 + "<br>";
var pixelObject = {};
for(var i = 0; i < data.length; i += 4){
var rgba = "rgba("+data[i]+","+data[i+1]+","+data[i+2]+","+data[i+3]+")";
pixelObject[rgba] = pixelObject[rgba] ? pixelObject[rgba]+1 : 1;
}
Out.innerHTML += "Total Whitespace: " + pixelObject["rgba(255,255,255,255)"] + "<br>";
Out.innerHTML += "Total Pixels In "+ key +": " + ((data.length/4)-pixelObject["rgba(255,255,255,255)"]) + "<br>";
};
})(new Image(),key)}
};
<table>
<tr>
<td>
<canvas id="B" width="100%" height="100%"></canvas>
</td>
<td id="BOut">
</td>
</tr>
<tr>
<td>
<canvas id="M" width="100%" height="100%"></canvas>
</td>
<td id="MOut">
</td>
</tr>
<tr>
<td>
<canvas id="W" width="100%" height="100%"></canvas>
</td>
<td id="WOut">
</td>
</tr>
</table>
Chcesz poznać prawdziwy najdłuższy glifów, nie tylko zgadywać?
I nie mówię tylko o literach, cyfrach i typowych symbolach (!, @ Itd.). Mam na myśli najdłuższy glif ze wszystkich 32 834 znaków UTF-16.
Zacząłem więc od odpowiedzi @NK, która miała programowe rozwiązanie tego problemu, i wprowadziłem kilka drobnych modyfikacji:
var capsIndex = 65;
var smallIndex = 97;
var div = document.createElement('div');
div.style.float = 'left';
document.body.appendChild(div);
var highestWidth = 0;
var elem;
for(var i = capsIndex; i < 32834; i++) {
div.innerText = String.fromCharCode(i);
var computedWidth = window.getComputedStyle(div, null).getPropertyValue("width");
if(highestWidth < parseFloat(computedWidth)) {
highestWidth = parseFloat(computedWidth);
elem = String.fromCharCode(i);
}
}
div.innerHTML = '<b>' + elem + '</b>' + ' won';
Po uruchomieniu tego i czekaniu (i czekaniu) daje wynik ௌ won
.
I oto masz, najdłuższa postać w UTF-32! Zauważ, że w niektórych czcionkach najdłuższym glifem jest ﷽, ale inne czcionki (szczególnie monospace) nakładają się na znaki, tak jak w przypadku czcionki uwzględnianej przez program.