SENI #003
SENI #003
SENI adalah kegiatan yang diprakarsai oleh
由左耳朵耗子--陈皓: Kerjakan setidaknya satu pertanyaan algoritma leetcode setiap minggu, baca dan komentari setidaknya satu artikel teknis berbahasa Inggris, pelajari setidaknya satu keterampilan teknis, dan bagikan artikel yang berisi opini dan pemikiran. (Artinya, Algoritma, Review, Tip, dan Share disebut sebagai SENI) dan bertahan setidaknya selama satu tahun.
SENI 003
Ini adalah artikel ketiga, dan tulisannya relatif buruk. Saya berharap ini akan menjadi lebih baik dan lebih baik lagi di masa depan.
Pertanyaan algoritma algoritma
pertanyaan algoritma leetcode 151 Membalikkan Kata dalam sebuah String (membalikkan kata dalam sebuah string) Mungkinkah: Sedang
Given an input string, reverse the string word by word.
Example:
Input: "the sky is blue",
Output: "blue is sky the".
Note:
A word is defined as a sequence of non-space characters.
Input string may contain leading or trailing spaces. However, your reversed string should not contain leading or trailing spaces.
You need to reduce multiple spaces between two words to a single space in the reversed string.
Follow up: For C programmers, try to solve it in-place in O(1) space.
给定一个字符串,逐个翻转字符串中的每个单词。
示例:
输入: "the sky is blue",
输出: "blue is sky the".
说明:
无空格字符构成一个单词。
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
进阶: 请选用C语言的用户尝试使用 O(1) 时间复杂度的原地解法。
Jika Anda tidak mempertimbangkan masalah ruang, algoritma ini relatif sederhana. Balikkan seluruh string, lalu balikkan setiap kata. Kesulitan dari pertanyaan ini adalah bagaimana menghilangkan kelebihan spasi, antara lain spasi di awal, spasi di akhir, dan spasi berlebih antar kata. Implementasinya adalah sebagai berikut:
void ReverseString(char* str,int min,int max) {
int i = min;
int j = max;
while (i < j) {
char temp = * (str + i);
* (str + i) = * (str + j);
* (str + j) = temp;
i++;
j--;
}
}
//翻转字符串
void reverseWords(char *fdg) {
RemoveEmptyChar(fdg);
ReverseString(fdg,0,strlen(fdg) -1);
int i = 0;
int j = 0;
while (*(fdg + j)) {
if (*(fdg + j) == ' ') {
ReverseString(fdg,i,j-1);
i=j+1;
}
j++;
}
ReverseString(fdg,i,j-1);
}
//去掉空格
void RemoveEmptyChar(char* str) {
//先去掉尾部的空格
int j = strlen(str) -1;
while (*(str + j) == ' ') {
*(str + j) = '\0';
j--;
}
//去掉头部的空格
int i = 0;
while (*(str + i) == ' ') {
i++;
}
if(i > 0){
int count = 0;
while ((count < strlen(str) - i) && *(str +i + count)) {
*(str + count) = *(str +i + count);
count++;
}
*(str + count) = '\0';
}
//去掉中间的空格
int m = 0;
int flag = 0;
while (m < strlen(str)) {
if (*(str + m) == ' '){
flag++;
m++;
continue;
}
if (flag > 1) {
int count = 0;
while ((count < strlen(str) -m)) {
*(str + m - flag + 1 + count) = *(str + m + count);
count++;
}
*(str + m - flag + 1 + count) = '\0';
m = m - flag ;
}
flag = 0;
m++;
}
}
Algoritma ini mempunyai masalah pada leetcode yaitu time out. Seperti yang Anda lihat di atas, tidak ada ruang untuk optimasi dalam metode membalik string. Batas waktu harus disebabkan oleh metode menghilangkan spasi. Penerapan metode menghilangkan spasi adalah jika ditemukan spasi tambahan, string setelah spasi akan dipindahkan ke depan. Dalam kasus terburuk, jumlah perpindahan karakter harus kira-kira: karakter kedua dipindahkan satu kali, karakter ketiga dipindahkan dua kali, dan karakter ke-n dipindahkan n-1 kali, kompleksitas waktunya adalah O(n<sup>2</sup>). Sebenarnya tidak perlu berpindah berkali-kali. Satu karakter hanya perlu dipindahkan satu kali. Metode yang ditingkatkan untuk menghilangkan spasi adalah sebagai berikut:
void RemoveEmptyChar1(char* str) {
char * i = str;
char * j = str;
while (*i && (*i == ' ')) {
if (i == str) {
j = i;
while (*j && (*j == ' ')) {
j++;
}
if (!*j) {//说明全是空格
i = j;
}
while (*j && (*j != ' ')) {
*i = *j;
*j = ' ';
i++;
j++;
}
}
else{
if (*(i+1) == ' ') {
j = i+ 1;
while (*j && (*j == ' ')) {
j++;
}
i++;
while (*j && (*j != ' ')) {
*i = *j;
*j = ' ';
i++;
j++;
}
}
else{
i++;
}
}
}
//先去掉尾部的空格
int m = strlen(str) -1;
while (*(str + m) == ' ') {
*(str + m) = '\0';
m--;
}
}
Setelah perbaikan, waktu berjalan leetcode adalah 4ms, dan jawaban terbaik yang dikirimkan pada leetcode adalah 0ms. Saya melihatnya dan menemukan bahwa metode membalik senarnya sama dengan milik saya. Perbedaannya terletak pada cara menghilangkan spasi. Cara menghilangkan spasi dalam 0ms adalah sebagai berikut:
void updateString(char *s) {
int i = 0;
int end = 0;
int index = 0;
bool flag = false;
while (s[i] == ' ') {
i++;
}
while (s[i] != '\0') {
if (s[i] == ' ') {
flag = true;
} else {
if (flag) {
index = end + 1;
end = index + 1;
flag = false;
} else {
index = end;
end++;
}
if (i > index) {
s[index] = s[i];
s[i] = ' ';
}
}
i++;
}
s[end] = '\0';
}
Terlihat tidak ada loop yang bersarang dalam implementasinya, artinya ia hanya menggunakan satu loop untuk menyelesaikannya. Saat dia menerapkannya, dia memindahkan paling banyak satu karakter dalam satu waktu. Adapun implementasi saya di atas, dalam satu loop, jika perlu dipindahkan, setidaknya satu kata akan dipindahkan, semuanya dengan loop bersarang.
Ulasan
Artikel berikut berasal dari: https://littlebitesofcocoa.com/251-face-aware-image-views-with-aspectfillfaceaware;. Ini berbicara tentang penggunaan aspekfillfaceaware untuk menyadari bahwa ketika mengatur gambar untuk imageView, jika gambar berisi wajah, wajah dapat secara otomatis ditampilkan di tengah.
Tampilan Gambar Face Aware dengan AspectFillFaceAware (gunakan AspectFillFaceAware agar imageView mengenali wajah)
Saat menggunakan UIImageViews, terkadang mode konten bawaan dapat membatasi gaya kita.
Saat menggunakan UIImageViews, terkadang mode konten bawaan merusak gaya kita dan tidak dapat memenuhi kebutuhan kita.
Seringkali, kami menampilkan foto orang. Dalam kasus ini, akan sangat bagus jika tampilan gambar dapat diminta untuk memotong foto di sekitar wajah orang tersebut dengan cerdas.
Seringkali, kami menampilkan foto orang. Dalam kasus ini, akan sangat bagus jika tampilan gambar dapat dengan cerdas memotong foto di sekitar wajah orang tersebut.
Hari ini kita akan memeriksa perpustakaan dari Beau Nouvelle yang disebut AspectFillFaceAware. Ini sangat sederhana, mari kita lihat.
Hari ini kita akan melihat perpustakaan kelas dari Beau Nouvelle yang disebut AspectFillFaceAware. Ini sangat sederhana, mari kita lihat.
AspectFillFaceAware pada dasarnya hanyalah ekstensi pada UIImageView. Ini menyediakan dua cara untuk mengonfigurasi tampilan gambar menjadi “sadar wajah”.
AspectFillFaceAware pada dasarnya hanyalah perpanjangan dari UIImageView. Ini menyediakan dua metode untuk mengkonfigurasi tampilan gambar untuk “pengenalan wajah”.
Yang pertama ada di Interface Builder, kita dapat mengaktifkan fitur tersebut dengan mengaktifkan fitur di Inspector. (Tidak melihat opsinya? Jalankan proyek Anda sekali, maka proyek itu akan muncul).
Cara pertama adalah di Interface Builder, kita dapat mengaktifkan fitur tersebut dengan menelusuri Fitur di Inspektur. (Tidak melihat opsinya? Jalankan proyek Anda sekali dan proyek itu akan muncul).
<img src=“/img/15334638167496.jpg” lebar=“50%” tinggi=“50%” /> Berikut tampilannya:

Kita juga dapat mengaktifkan fungsionalitas dalam kode dengan mengatur tampilan gambar menggunakan fungsi baru ini:
Kita juga dapat menggunakan fitur baru ini melalui kode:
imageView.set(gambar: avatar, focusOnFaces: benar) Kita bahkan dapat menampilkan radius sudut cepat pada lapisan tampilan gambar untuk mencoba fungsi “sadar wajah” pada tampilan melingkar. (yaitu avatar pengguna):
Kita bahkan dapat menampilkan radius sudut cepat pada lapisan tampilan gambar untuk mencoba fitur “pengenalan wajah” pada tampilan melingkar. (yaitu avatar pengguna):
misalkan radius = imageView.bounds.size.width / 2.0 imageView.layer.cornerRadius = radius
Di bawah tenda, perpustakaan menggunakan CIDetector akurasi rendah dengan tipe CIDetectorTypeFace untuk menangani deteksi wajah sebenarnya. Ingin menyelam lebih dalam di sini? Kami membahas CIDetectors di Bite #87.
Di bawah tenda, perpustakaan menggunakan CIDetector presisi rendah dengan tipe CIDetectorTypeFace untuk menangani deteksi wajah sebenarnya. Ingin mempelajari lebih dalam? Kami memperkenalkan pendekatan CIDetectors di Bite #87.
Kiat
####1 Bagaimana cara mengatur breakpoint untuk metode sistem saat menggunakan Xcode untuk melakukan debug? Jawabannya adalah titik putus. Misalnya, untuk metode setContentInset, break point, Anda dapat menggunakan perintah berikut:
breakpoint set -S setContentInset:
Untuk detailnya, silakan merujuk ke: https://www.jianshu.com/p/8e9fc9a8ab78?from=jiantop.com
####2 Pengoptimalan UITableView Optimasi UITableView bisa dikatakan menjadi topik yang tidak akan pernah ketinggalan zaman dalam pengembangan iOS. Berikut adalah ringkasan ide pengoptimalan. Anda dapat mencari sendiri metode spesifiknya di Google. Ide umumnya adalah sebagai berikut:
-
Kurangi jumlah perhitungan CPU/GPU 1.1 Mekanisme penggunaan kembali sel 1.2 Simpan tinggi sel dan bingkai kontrol dalam sel dalam model 1.3 Kurangi tingkat kontrol di dalam sel 1.4 Dapatkan efek sudut membulat pada avatar dengan menutupi gambar sudut membulat
-
Muat sel sesuai permintaan 2.1 Hanya memuat sel yang terlihat dalam metode cellForRow: 2.2 Pantau pengguliran cepat tampilan tabel dan simpan indeks tiga baris sebelum dan sesudah rentang gulir target
-
Pemrosesan sel yang tidak sinkron 3.1 Pemuatan gambar jaringan secara asinkron 3.2 Menggambar gambar lokal secara asinkron 3.3 Gambar UIView asinkron 3.4 Gambar NSString yang tidak sinkron 3.5 Gambar UILabel asinkron
Bagikan
Berbagi pertanyaan hari ini, saya melihat pertanyaan ini di grup hari ini
<img src=“/img/20180809225650469.png” lebar=“50%” tinggi=“50%” />
Yang mana yang akan kamu pilih? Pilih D?
Dari pengetahuan sebelumnya, saya harus memilih D, tetapi ketika saya melihat seseorang mengatakan untuk memilih B, saya mencobanya. Kode tesnya adalah sebagai berikut:
- (void)viewDidLoad {
[super viewDidLoad];
for (int i =0; i < MAXFLOAT; i++) {
@autoreleasepool{
UIImage *img = [[UIView alloc] init];// A
UILabel *lab = [[UILabel alloc] init];// B
NSString *str = @"abc";
str = [str stringByAppendingString:@"xyz"];// C
}
}
}
Hasilnya memang B. B akan menyebabkan daya ingat terus bertambah. Setelah pengujian, ditemukan bahwa terlepas dari autoreleasepool, B akan menyebabkan memori terus bertambah. Dua lainnya tidak akan menyebabkan memori terus bertambah. Ini aneh. Masuk akal bahwa setelah menambahkan @autoreleasepool, memori akan dilepaskan secara otomatis ketika mencapai nilai tertentu. Penjelasan di grup adalah:
- Terkait dengan benang
- Apple telah mengoptimalkan loop for. Jika bukan UIView dan subkelasnya, maka akan diproses di sub-thread.
- Objek UIView akan otomatis dibuat di thread utama
- Jika Anda meletakkan UIImage di thread utama untuk diproses, memori akan tetap melonjak.
- Metode rilis kumpulan rilis otomatis thread utama berbeda dengan metode rilis thread anak.
Tapi saya masih tidak mengerti alasannya: 1 lab adalah variabel lokal, kecuali tanda kurung siku kanan dari perulangan for harus dilepaskan. 2 Menambahkan @autoreleasepool, yang harus dirilis saat memori mencapai puncaknya. ? ? ?
What to read next
Want more posts about ARTS?
Posts in the same category are usually the best next step for reading more on this topic.
View same categoryWant to keep following #iOS?
Tags are useful for related tools, specific problems, and similar troubleshooting notes.
View same tagWant to explore another direction?
If you are not sure what to read next, return to the homepage and start from categories, topics, or latest updates.
Back home