Я намагаюся зробити якесь динамічне програмування на основі кількості символів у реченні. Яка літера англійського алфавіту займає найбільше пікселів на екрані?
Я намагаюся зробити якесь динамічне програмування на основі кількості символів у реченні. Яка літера англійського алфавіту займає найбільше пікселів на екрані?
Відповіді:
Хм, подивимось:
аааааааааааааааааааааааааааааааааааааа
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
ccccccccccccccccccccccccccccccccccccccc
dddddddddddddddddddddddddddddddddddddddd
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
ffffffffffffffffffffffffffffffffffffffffff
gggggggggggggggggggggggggggggggggggggg
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
llllllllllllllllllllllllllllllllllllllllll
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
ooooooooooooooooooooooooooooooooooooooooo
pppppppppppppppppppppppppppppppppppppppp
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
ssssssssssssssssssssssssssssssssssssssss
tttttttttttttttttttttttttttttttttttttttt
уууууууууууууууууууууууууууууууууууууууу
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
ММММММММММММММММММММММММММММММММММММММММММ
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
W виграє.
Звичайно, це дурний емпіричний експеримент. Немає однозначної відповіді, який лист найширший. Це залежить від шрифту. Тож вам доведеться зробити аналогічний емпіричний експеримент, щоб з’ясувати відповідь для свого оточення. Але факт полягає в тому, що більшість шрифтів дотримуються одних і тих же конвенцій, а капітал W буде найширшим.
Позначення цих ширин символів у формі співвідношення (W = 100), записаних тут, використовуючи саме цей шрифт прикладу:
https://gist.github.com/imaurer/d330e68e70180c985b380f25e195b90c
На додаток до дивовижної практичної відповіді Неда Батчелдера, тому що я прийшов сюди цікавитись цифрами:
00000000000000000000000000000000000000000000
1111111111111111111111111111111111111111
222222222222222222222222222222222222222222
3333333333333333333333333333333333333333
444444444444444444444444444444444444444444
555555555555555555555555555555555555555555
666666666666666666666666666666666666666666
777777777777777777777777777777777777777777
888888888888888888888888888888888888888888
999999999999999999999999999999999999999999
font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
font-size: 15px;
О, цей Apple, завжди намагаючись бути трохи іншим ....
font-variant-numeric
: пропорційні цифри допускають різну ширину, як у гліфі, так і в інтервалі, тоді як табличні цифри повинні дотримуватися аналогічних правил, як одношарові шрифти.
Як щодо програмного рішення?
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';
Капітал "М" умовно найширший.
Залежно від вашої платформи, може бути спосіб «отримати ширину» з рядка або функції DrawText () якось із властивістю ширини.
Я зробив би простий алгоритм, який використовував потрібний шрифт, а потім пробіг по альфабету і зберігав його в невеликому конфігурації або просто обчислював його при ініціалізації як цикл від А до Я не так важко.
Це також залежить від шрифту. Я зробив це 1 або 2 роки тому з Processing і Helvetica, і це ILJTYFVCPAXUZKHSEDORGNBQMW в порядку збільшення пікселів. Ідея полягає в тому, щоб намалювати текст на полотні за допомогою шрифту, який ви шукаєте, порахувати пікселі, а потім сортувати за допомогою HashMap або словника.
Звичайно, це може не бути безпосередньо відносно вашого використання, оскільки це обчислює піксельну площу, а не просто ширину. Можливо, теж буде трохи зайвого.
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 в Chrome - W виграє .
Рішення для обчислення ширини шрифтів трохи схоже на рішення, розміщене на xxx, було розміщено Алексеєм Майклом у своєму блозі (який досить смішно пов'язав мене тут).
Підсумок:
Оригінальна публікація: http://alexmic.net/letter-pixel-count/
Код:
# -*- 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()
Це залежатиме від шрифту. Я створив би невелику програму на мові програмування, яка вам найбільше подобається, де ви малюєте кожну букву алфавіту в растровий розмір m. Ініціалізуйте кожен піксель білим кольором. Потім підрахуйте кількість білих пікселів після того, як ви намалювали кожну букву, і збережіть це число. Найбільша кількість, яку ви знайдете, - це та, яку ви шукаєте.
EDIT: Якщо вас насправді цікавить, який з них займає найбільший прямокутник (але схоже, що ви насправді після цього, а не пікселі), ви можете використовувати різні дзвінки API, щоб знайти розмір, але це залежить від Ваша мова програмування. Наприклад, у Java ви б використовували клас FontMetrics.
Я знаю, що прийнята відповідь тут W, W - WIN.
Однак у цьому випадку W також для Width. Приклад дослідження використовував простий тест на ширину для вивчення пікселів, але це була лише ширина, а не загальна кількість пікселів. Як простий приклад лічильника, прийнята відповідь передбачає, що O і Q займають однакову кількість пікселів, але вони займають однакову кількість місця.
Таким чином, W займає найбільше місця . Але хіба це всі пікселі, якими він тріснув?
Давайте отримаємо кілька емпіричних даних. Я створив imgur-зображення із наступних B, M та W. Потім я проаналізував їх кількість пікселів (див. Нижче), ось результати:
B: 114 пікселів
M: 150 пікселів
Ш: 157 пікселів
Ось як я подав їх у полотно та аналізував необроблені дані пікселів із зображень.
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>
Хочете дізнатися справжній найдовший гліф, а не лише здогадуватися?
І я не просто кажу про букви, цифри та загальні символи (!, @ Тощо). Я маю на увазі найдовший гліф з усіх 32 834 символів UTF-16.
Тож я почав з відповіді від @NK, яка мала програмне рішення, і внесла деякі незначні зміни до нього:
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';
Після запуску цього і очікування (і очікування) він дає вихід ௌ won
.
І ось у вас це, найдовший персонаж UTF-32! Зауважте, що для деяких шрифтів найдовший гліф дорівнює ﷽, а інші шрифти (особливо монопростірні) перекривають символи, як у випадку з шрифтом, який програма враховує у програмі.